在Pandas数据帧中有效地找到id上一列的最大值

时间:2015-07-10 01:01:45

标签: python indexing pandas dataframe

我正在处理一个非常大的数据帧(350万X 150,并且在打开时需要25 gig的内存)我需要在id号和日期上找到最多一列并保持 具有最大值的行。每行是特定日期的一个id的记录观察,我还需要最新的日期。

这是动物测试数据,其中每个id和日期有20个附加列seg1-seg20连续填充测试日信息,例如,第一测试数据填充seg1,第二测试数据填充seg2等。 "值"字段表示已填充了多少个段,换句话说,已完成了多少个测试,因此具有最大值"值的行#34;拥有最多的测试数据。理想情况下,我只想要这些行而不是前一行。例如:

df= DataFrame({'id':[1000,1000,1001,2000,2000,2000], 
          "date":[20010101,20010201,20010115,20010203,20010223,20010220],
          "value":[3,1,4,2,6,6], 
          "seg1":[22,76,23,45,12,53],
          "seg2":[23,"",34,52,24,45],
          "seg3":[90,"",32,"",34,54],
          "seg4":["","",32,"",43,12],
          "seg5":["","","","",43,21],
          "seg6":["","","","",43,24]})
df
       date    id  seg1 seg2 seg3 seg4 seg5 seg6  value
0  20010101  1000    22   23   90                     3
1  20010201  1000    76                               1
2  20010115  1001    23   34   32   32                4
3  20010203  2000    45   52                          2
4  20010223  2000    12   24   34   43   43   41      6
5  20010220  2000    12   24   34   43   44   35      6

最终它应该是:

       date    id  seg1 seg2 seg3 seg4 seg5 seg6  value
0  20010101  1000    22   23   90                     3
2  20010115  1001    23   34   32   32                4
4  20010223  2000    12   24   34   43   43   41      6

我首先尝试使用.groupby(' id')。max但无法找到使用它来删除行的方法。结果数据框必须包含ORIGINAL ROWS,而不仅仅是每个id的每列的最大值。我目前的解决方案是:

for i in df.id.unique():
    df =df.drop(df.loc[df.id==i].sort(['value','date']).index[:-1])

但每次运行大约需要10秒钟,我假设因为它每次都试图调用整个数据帧。有760,000个唯一ID,每个都有17位数字,因此在这个速度下使用它会花费太长时间。

还有其他方法更有效吗?目前,它将每个列作为"对象"但是将相关列转换为整数的最低位似乎也无济于事。

1 个答案:

答案 0 :(得分:1)

我尝试使用groupby('id').max()并且它可以工作,它也会删除行。您记得重新分配df变量吗?因为这个操作(以及几乎所有的Pandas'操作)都不在原地。

如果你这样做:

df.groupby('id', sort = False).max()

你会得到:

          date  value
id                   
1000  20010201      3
1001  20010115      4
2000  20010223      6

如果您不希望id作为索引,请执行以下操作:

df.groupby('id', sort = False, as_index = False).max()

你会得到:

     id      date  value
0  1000  20010201      3
1  1001  20010115      4
2  2000  20010223      6

但我不知道这样做会不会更快。

更新

这样就不会重置索引:

df.iloc[df.groupby('id').apply(lambda x: x['value'].idxmax())]

你会得到:

           date    id  seg1 seg2 seg3 seg4 seg5 seg6  value
0  20010101  1000    22   23   90                     3
2  20010115  1001    23   34   32   32                4
4  20010223  2000    12   24   34   43   43   43      6