以以下数据框为例,如何识别彼此相邻的重复项并将信息添加到另一列?
G_NUM PRIM P_NUM
0 15 True 135
1 9 False 147
2 9 True 264
3 9 False 537
4 2 False 154
5 10 False 222
6 10 False 370
7 10 False 188
8 14 True 215
我希望输出显示为以下DF。 PRI列具有一个元组,用于存储序列号,组中元素的总数以及组中的优先级。
对于第0行(G_NUM = 5),组中只有一个,所以它是1/1,元组的最后一个元素保持优先级,在这种情况下为1。我想将PRI列设置为(1,1,1)。
对于第1-3行(G_Num = 9),有3个行,因此分别为1 / 3、2 / 3和3/3。对于优先级,我希望那些PRIM = True具有更高的优先级。如果两个相邻的成员具有相同的PRIM状态,则第一个出现的成员具有更高的优先级。
如何做到这一点?谢谢!
G_NUM PRIM P_NUM PRI
0 15 True 135 (1,1,1)
1 9 False 147 (1,3,2)
2 9 True 264 (2,3,1)
3 9 False 537 (3,3,3)
4 2 False 154 (1,1,1)
5 10 False 222 (1,3,1)
6 10 False 370 (1,3,2)
7 10 False 188 (1,3,3)
8 14 True 215 (1,1,1)
答案 0 :(得分:1)
一旦您拥有df
,就像上面的第一个一样,就可以像这样df.groupby
使用
In [1]: grouped = df.groupby('G_NUM').PRIM
In [2]: tuples = list(zip(grouped.cumcount() + 1, grouped.transform(len), grouped.transform(lambda x: np.argsort(~x.values, kind='mergesort')+1)))
In [3]: tuples
Out[3]: [(1, 1, 1),
(1, 3, 2),
(2, 3, 1),
(3, 3, 3),
(1, 1, 1),
(1, 3, 1),
(2, 3, 2),
(3, 3, 3),
(1, 1, 1)]
由您决定如何将其恢复为原始的df
。请注意您的问题中的两个错误:(1)G_NUM
中的第一个df
是15而不是5,(2)第5-7行的PRI
序列等级索引是错误的因为它们不会增加。
您应该阅读Pandas
中的split-apply-combine技术。我上面的代码中的zip
中的元素用于以下目的:
pd.cumcount()
计算给定元素之前有多少项,然后将其应用于grouped
对象,将计算结果投影到每个组上。grouped.transform(len)
计算每个组中元素的数量,并将其作为每个给定观察值的标量值。 grouped.transform(lambda x: np.argsort(~x.values)+1)
处理优先级规范:np.argsort
查找列表中给定元素的排名-换句话说,它给出了排列列表时所依据的排列。通过将argsort应用于〜x.values,我们以降序排序。 (我不知道实际上是否有必要使用kind
关键字;我坚持采用mergesort,以便使排序稳定,因此只要PRIM
值相等,原始顺序就会优先;此刻我不记得quicksort
使用的numpy
作为其默认值是否被修改为稳定)。