我的数据框如下所示:
A B C D
date
2015-01-01 1 1 2 3
2015-01-02 1 2 3 3
2015-01-03 1 2 1 3
2015-01-04 3 2 1 1
2015-01-05 3 2 2 1
2015-01-06 1 1 2 3
2015-01-07 1 2 3 3
2015-01-08 1 2 1 3
2015-01-09 3 2 1 1
2015-01-10 3 2 2 1
2015-01-11 3 2 2 1
基本规则:我想确定每行的2个最小值,并将这些值设置为1.其他值应设置为0.
附加规则:
1 1 1 1 should be 1 1 1 1
1 2 2 2 should be 1 1 1 1
1 2 2 3 should be 1 1 1 0
1 2 3 4 should be 1 1 0 0
我希望您可以遵循规则,并且在开始时数据框应该是
date A B C D
2015-01-01 1 1 0 0
2015-01-02 1 1 0 0
2015-01-03 1 0 1 0
2015-01-04 0 0 1 1
2015-01-05 0 1 1 1
2015-01-06 1 1 0 0
2015-01-07 1 1 0 0
2015-01-08 1 0 1 0
2015-01-09 0 0 1 1
2015-01-10 0 1 1 1
2015-01-11 0 1 1 1
修改
“也许你想要使用method ='first rank'我认为这样可行 - EdChum” 数据框的结果:
A B C D
date
2015-01-01 1 2 3 4
2015-01-02 1 2 3 4
2015-01-03 1 3 2 4
2015-01-04 4 3 1 2
2015-01-05 4 2 3 1
2015-01-06 1 2 3 4
2015-01-07 1 2 3 4
2015-01-08 1 3 2 4
2015-01-09 4 3 1 2
2015-01-10 4 2 3 1
2015-01-11 4 2 3 1
答案 0 :(得分:3)
我认为这可以满足您的需求:
In [3]:
mask = df.rank(method='dense', axis=1) <= 2
df[mask] = 1
df[~mask] = 0
df
Out[3]:
A B C D
date
2015-01-01 1 1 1 0
2015-01-02 1 1 0 0
2015-01-03 1 1 1 0
2015-01-04 0 1 1 1
2015-01-05 0 1 1 1
2015-01-06 1 1 1 0
2015-01-07 1 1 0 0
2015-01-08 1 1 1 0
2015-01-09 0 1 1 1
2015-01-10 0 1 1 1
2015-01-11 0 1 1 1
这将逐行返回rank
个值,并且传递method='dense'
将根据第一次看到值进行排名,并在看到新组时递增1,您可以更改2
到任意n
值,排名与行中的值是否为整数和顺序无关。
答案 1 :(得分:2)
如果你想扩展4列,或许可以尝试类似下面的内容,那么前面解决方案中的掩码思想就是我实现它的方式,但是你可以指定你想要两个最小值:
mask = df.apply(lambda x: x.isin(x.nsmallest(2)), axis=1)
df[mask] = 1
df[~mask] = 0
df
A B C D
2015-01-01 1 1 0 0
2015-01-02 1 1 0 0
2015-01-03 1 0 1 0
2015-01-04 0 0 1 1
2015-01-05 0 1 1 1
2015-01-06 1 1 0 0
2015-01-07 1 1 0 0
2015-01-08 1 0 1 0
2015-01-09 0 0 1 1
2015-01-10 0 1 1 1
2015-01-11 0 1 1 1
我担心这个解决方案在大型数据集上的性能,但它应该能为您提供所需的答案