【发布时间】:2016-04-09 18:36:21
【问题描述】:
我正在尝试使用 Pandas 使用 groupby 操作的结果来修改一个巨大的数据集。 我需要的是找到数据组的最小值,同时忽略零,但如果它是组中唯一的值,则返回相同的零。
考虑这个虚拟数据:
>>> a=pd.DataFrame(dict(item_id=[1,1,1,2,2,2], pos_id=[3,7,7,7,7,7], target='T1 T2 T3 T1 T2 T3'.split(), val=[8,0,0,41,0,55]))
>>> a
item_id pos_id target val
0 1 3 T1 8
1 1 7 T2 0
2 1 7 T3 0
3 2 7 T1 41
4 2 7 T2 0
5 2 7 T3 55
对于 pos_id == 7 和 target == 'T2' 中的每个 item_id,我想获得整个组中最小的非零 val(忽略目标),并将其替换为这个!
所以,我想最后得到这个:
item_id pos_id target val
0 1 3 T1 8 <-- this row has the wrong pos_id and is ignored
1 1 7 T2 0 <-- this one maintains zero (all group has zeros)
2 1 7 T3 0
3 2 7 T1 41
4 2 7 T2 41 <-- this one gets the smallest of item_id group
5 2 7 T3 55
我试过这个:
>>> a.ix[(a.pos_id == 7) & (a.target == 'T2'), 'val'] = a.ix[a.pos_id == 7].groupby('item_id').val.min().values
但它不起作用,因为没有忽略零。而且我不能简单地忽略它们,因为作业两边的系列会有不同的大小!
>>> a.ix[(a.pos_id == 7) & (a.target == 'T2'), 'val'].size, a.ix[(a.pos_id == 7) & (a.val != 0)].groupby('item_id').val.min().values.size
(2, 1)
我也尝试在这些零中设置一个高值,所以第一个几乎会成功:
>>> a.ix[(a.pos_id == 7) & (a.val == 0), 'val'] = 9999
>>> a
item_id pos_id target val
0 1 3 T1 8
1 1 7 T2 9999
2 1 7 T3 9999
3 2 7 T1 41
4 2 7 T2 9999
5 2 7 T3 55
但是:
>>> a.ix[(a.pos_id == 7) & (a.target == 'T2'), 'val'] = a.ix[a.pos_id == 7].groupby('item_id').val.min().values
>>> a
item_id pos_id target val
0 1 3 T1 8
1 1 7 T2 9999 <-- this one should maintain zero...
2 1 7 T3 9999
3 2 7 T1 41
4 2 7 T2 41 <-- this one works!
5 2 7 T3 55
但现在我必须将不应修改的值归零... 哦,那一定是更好的方法!
请问,我如何在一个更简单的步骤中通过忽略某些值来设置这个值?并且还请考虑到性能很重要,因为数据集有几 GB...
谢谢!
【问题讨论】: