pandas:按重复列值对行进行分组,保持组中每列的最大绝对值

时间:2018-01-25 13:05:00

标签: python-3.x pandas pandas-groupby

我正在尝试将df['new_time']的某些条目的重复日期时间的pandas DataFrame缩减为每个不同df['new_time']的单行条目。

考虑每组重复new_time,我想保留与每个其他列的最大值(对于日期时间df.index)或绝对最大值(对于df['A', 'B', 'C', 'D'])对应的值在小组中。

这样的DataFrame df就像:

import pandas as pd
from datetime import datetime
df = pd.DataFrame({'A':[9, 7, 4, -2], 'B':[5, 6, -4, -5], 'C':[-5, -6, 7, -3],
                  'D':[9, 2, 7, 8], 'new_time':[datetime(2000, 1, 1, 0, 4, 0),
                  datetime(2000, 1, 1, 0, 4, 0), datetime(2000, 1, 1,0 ,1, 0),
                  datetime(2000, 1, 1, 0, 10, 0)]}, 
                  index=pd.date_range('20000101', freq='T', periods=4),
                  )
df.index.name = 'time'
df
     

,并提供:

                      A   B   C  D             new_time
time
2000-01-01 00:00:00   9   5  -5  9  2000-01-01 00:04:00
2000-01-01 00:01:00   7   6  -6  2  2000-01-01 00:04:00
2000-01-01 00:02:00   4  -4   7  7  2000-01-01 00:01:00
2000-01-01 00:03:00  -2  -5  -3  8  2000-01-01 00:10:00

应成为(如果按df['new_time']排序):

                      A   B   C  D             new_time
time
2000-01-01 00:02:00   4  -4   7  7  2000-01-01 00:01:00
2000-01-01 00:01:00   9   6  -6  9  2000-01-01 00:04:00
2000-01-01 00:03:00  -2  -5  -3  8  2000-01-01 00:10:00

请注意,第二行现在包含原始df的前两行的值。

我一直在尝试

df.loc[df.groupby('new_time')['A'].idxmax()]

df.groupby('new_time').apply(lambda x: x[np.abs(x) == np.max(np.abs(x))])

但我无法找到将此方法应用于所有列的方法,尤其是需要将max()应用于日期时间,max(abs())应用于其他列。

1 个答案:

答案 0 :(得分:2)

不那么容易:

#first create column from index for prevent losing
df1 = df.reset_index()
#select numeri and non numeric columns
cols1 = df1.select_dtypes(include=[np.number]).columns
cols2 = df1.select_dtypes(exclude=[np.number]).columns
print (cols1)
Index(['A', 'B', 'C', 'D'], dtype='object')
print (cols2)
Index(['time', 'new_time'], dtype='object')

#create dictionaries for aggregation by types
d1 = {x:lambda x: x[x.abs().idxmax()] for x in cols1}
d2 = {x:lambda x: x.max() for x in cols2}
d = {**d1, **d2}

#aggregate, create index from time and reorder columns to original
df = df1.groupby('new_time').agg(d).set_index('time').reindex(columns=df.columns)
print (df)
                     A  B  C  D            new_time
time                                               
2000-01-01 00:02:00  4 -4  7  7 2000-01-01 00:01:00
2000-01-01 00:01:00  9  6 -6  9 2000-01-01 00:04:00
2000-01-01 00:03:00 -2 -5 -3  8 2000-01-01 00:10:00
相关问题