Pandas:根据多指标数据帧子集的条件设置值的正确方法

时间:2015-01-17 17:29:43

标签: python pandas multi-index

我不确定如何在没有链式作业的情况下执行此操作(这可能无论如何都不会起作用,因为我正在设置副本)。

我不想采用多索引pandas数据帧的子集,测试小于零的值并将它们设置为零。

例如:

df = pd.DataFrame({('A','a'): [-1,-1,0,10,12],
                   ('A','b'): [0,1,2,3,-1],
                   ('B','a'): [-20,-10,0,10,20],
                   ('B','b'): [-200,-100,0,100,200]})

df[df['A']<0] = 0.0

给出

In [37]:

df

Out[37]:
    A   B
    a   b   a   b
0   -1  0   -20 -200
1   -1  1   -10 -100
2   0   2   0   0
3   10  3   10  100
4   12  -1  20  200

这表明它无法根据条件进行设置。或者,如果我做了一个链式任务:

df.loc[:,'A'][df['A']<0] = 0.0

这给出了相同的结果(并设置了复制警告)

我可以根据第一级是我想要的那个条件遍历每一列:

for one,two in df.columns.values:
    if one == 'A':
        df.loc[df[(one,two)]<0, (one,two)] = 0.0

给出了期望的结果:

In [64]:

df

Out[64]:
    A   B
    a   b   a   b
0   0   0   -20 -200
1   0   1   -10 -100
2   0   2   0   0
3   10  3   10  100
4   12  0   20  200

但不知何故,我觉得有一种更好的方法可以做到这一点,而不是循环遍历列。在熊猫中这样做的最佳方法是什么?

1 个答案:

答案 0 :(得分:17)

这是应用(以及使用MultiIndex切片器的主要动机之一),请参阅文档here

In [20]: df = pd.DataFrame({('A','a'): [-1,-1,0,10,12],
                   ('A','b'): [0,1,2,3,-1],
                   ('B','a'): [-20,-10,0,10,20],
                   ('B','b'): [-200,-100,0,100,200]})

In [21]: df
Out[21]: 
    A      B     
    a  b   a    b
0  -1  0 -20 -200
1  -1  1 -10 -100
2   0  2   0    0
3  10  3  10  100
4  12 -1  20  200

In [22]: idx = pd.IndexSlice

In [23]: mask = df.loc[:,idx['A',:]]<0

In [24]: mask
Out[24]: 
       A       
       a      b
0   True  False
1   True  False
2  False  False
3  False  False
4  False   True

In [25]: df[mask] = 0

In [26]: df
Out[26]: 
    A      B     
    a  b   a    b
0   0  0 -20 -200
1   0  1 -10 -100
2   0  2   0    0
3  10  3  10  100
4  12  0  20  200

由于您正在使用列索引的第1级,因此以下内容也可以使用。上面的例子比较一般,比如说你想为&#39; a&#39;。

这样做
In [30]: df[df[['A']]<0] = 0

In [31]: df
Out[31]: 
    A      B     
    a  b   a    b
0   0  0 -20 -200
1   0  1 -10 -100
2   0  2   0    0
3  10  3  10  100
4  12  0  20  200