在熊猫数据框中获得n个最小的行

时间:2016-03-11 21:16:13

标签: python pandas dataframe

我的数据框如下所示:

            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

2 个答案:

答案 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

我担心这个解决方案在大型数据集上的性能,但它应该能为您提供所需的答案