Pandas:按重复列值分组行,保留每个组中每列的最大绝对值。

3

我正在尝试对具有重复日期时间的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

Giving:

                      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个回答

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

谢谢@jezrael,当我运行cols1 = df1.select_dtypes(np.number).columnscols2 = df1.select_dtypes(exclude=np.number).columns时,我遇到了错误:TypeError: include and exclude must both be non-string sequences我使用的是numpy 1.13.1和pandas 0.20.3,这是一些已经改变的行为吗? - WJB
1
难题,我使用 pandas 0.22.0 和 numpy 1.12.1。或许可以帮助到你:cols1 = df1.select_dtypes(include=[np.number]).columns cols2 = df1.select_dtypes(exclude=[np.number]).columns - jezrael
明白了 :) 如果您更新答案,我会接受它。 - WJB
@WJB - 完成了 ;) 谢谢。 - jezrael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接