我正在处理一个非常大的数据帧(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位数字,因此在这个速度下使用它会花费太长时间。
还有其他方法更有效吗?目前,它将每个列作为"对象"但是将相关列转换为整数的最低位似乎也无济于事。
答案 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