获取由另一列索引的特定列的最新值(获取由另一列索引的指定列的最大值)

  • 本文关键字:获取 索引 一列 最大值 最新 python pandas
  • 更新时间 :
  • 英文 :


我有以下数据帧:

   obj_id   data_date   value
0  4        2011-11-01  59500    
1  2        2011-10-01  35200 
2  4        2010-07-31  24860   
3  1        2009-07-28  15860
4  2        2008-10-15  200200

我想得到这个数据的子集,这样对于每个'obj_id',我只有最新的(最大的'data_date''value'

我想出了一个解决方案,但感觉很糟糕。我想知道是否有人有更好的方法。我确信我一定错过了一些通过熊猫来实现这一目标的简单方法。

我的方法本质上是分组、排序、检索和重组,如下所示:

row_arr = []
for grp, grp_df in df.groupby('obj_id'):
    row_arr.append(dfg.sort('data_date', ascending = False)[:1].values[0])
df_new = DataFrame(row_arr, columns = ('obj_id', 'data_date', 'value'))

如果"obj_id"的数量非常多,则需要对整个数据帧进行排序,然后删除重复项以获得最后一个元素。

sorted = df.sort_index(by='data_date')
result = sorted.drop_duplicates('obj_id', keep='last').values

这应该更快(对不起,我没有测试它),因为你不必做自定义的agg函数,当有大量的键时,它会很慢。您可能认为对整个数据帧进行排序会更糟,但在实践中,python中的排序很快,而原生循环则很慢。

这是另一种可能的解决方案。不知道这是否是最快的(我怀疑…),因为我没有将其与其他方法进行比较。

df.loc[df.groupby('obj_id').data_date.idxmax(),:]

我喜欢crewbum的答案,可能这更快(对不起,还没有测试过,但我避免对所有内容进行排序):

df.groupby('obj_id').agg(lambda df: df.values[df['data_date'].values.argmax()])

它使用numpys"argmax"函数来查找出现最大值的行索引。

正如tommy.carstensen所指出的,由于一些函数现在有未来的警告,因此正在更新ainted1的答案。以下是对我有效的方法:

sorted = df.sort_values(by='data_date')
result = sorted.drop_duplicates('obj_id', keep='last')

groupby对象上的aggregate()方法可以用于在一个步骤中从groupby对象创建新的DataFrame。(不过,我不知道有什么更干净的方法可以提取DataFrame的第一行/最后一行。)

In [12]: df.groupby('obj_id').agg(lambda df: df.sort('data_date')[-1:].values[0])
Out[12]: 
         data_date  value
obj_id                   
1       2009-07-28  15860
2       2011-10-01  35200
4       2011-11-01  59500

您还可以对各个列执行聚合,在这种情况下,聚合函数适用于Series对象。

In [25]: df.groupby('obj_id')['value'].agg({'diff': lambda s: s.max() - s.min()})
Out[25]: 
          diff
obj_id        
1            0
2       165000
4        34640
df1 = pd.DataFrame({
'Id': ['00', '01', '02', '02', '01', '03'] ,
'date': ['1990-12-31 ','1990-12-27 ','1990-12-28 ',
         '1990-12-28 ','1992-12-27 ','1990-12-30 '] , 
 
 'Population': ['700','200','300','400','500','100']        
         })
print(df1)
"""
   Id         date Population
0  00  1990-12-31         700
1  01  1990-12-27         200
2  02  1990-12-28         300
3  02  1990-12-28         400
4  01  1992-12-27         500
5  03  1990-12-30         100
"""

Max1 = df1.groupby('Id').apply( lambda df : df['Population'].values[df['Population'].values.argmax()]  )

print(Max1)
"""
Id
00    700
01    500
02    400
03    100
dtype: object
"""
Min1 = df1.groupby('Id').apply(lambda df : df['Population'].values[df['Population'].values.argmin()])
print(Min1)
"""
Id
00    700
01    200
02    300
03    100
dtype: object
"""

方法2:

cc = df1.sort_values('Population', ascending=False).drop_duplicates(['Id'])
print(cc)
"""
   Id         date Population
0  00  1990-12-31         700
4  01  1992-12-27         500
3  02  1990-12-28         400
5  03  1990-12-30         100
"""

方法3:

aa = df1.groupby(['Id'],sort = False)['Population'].max()
print(aa)
"""
Id
00    700
01    500
02    400
03    100
Name: Population, dtype: object
"""

方法4:

res = df1.groupby(['Id'])['Population'].transform(max) == df1['Population']
print(df1[res])
"""
   Id         date Population
0  00  1990-12-31         700
3  02  1990-12-28         400
4  01  1992-12-27         500
5  03  1990-12-30         100
"""

我相信已经根据这个线程中的解决方案找到了更合适的解决方案。然而,我使用了数据帧的应用函数,而不是聚合函数。它还返回一个与原始数据帧具有相同列的新数据帧。

df = pd.DataFrame({
'CARD_NO': ['000', '001', '002', '002', '001', '111'],
'DATE': ['2006-12-31 20:11:39','2006-12-27 20:11:53','2006-12-28 20:12:11','2006-12-28 20:12:13','2008-12-27 20:11:53','2006-12-30 20:11:39']})
print df 
df.groupby('CARD_NO').apply(lambda df:df['DATE'].values[df['DATE'].values.argmax()])

原始

CARD_NO                 DATE
0     000  2006-12-31 20:11:39
1     001  2006-12-27 20:11:53
2     002  2006-12-28 20:12:11
3     002  2006-12-28 20:12:13
4     001  2008-12-27 20:11:53
5     111  2006-12-30 20:11:39

返回的数据帧:

CARD_NO
000        2006-12-31 20:11:39
001        2008-12-27 20:11:53
002        2006-12-28 20:12:13
111        2006-12-30 20:11:39

最新更新