【问题标题】:Pandas : Proper way to set values based on condition for subset of multiindex dataframePandas:根据条件为多索引数据帧的子集设置值的正确方法
【发布时间】:2015-03-16 03:13:33
【问题描述】:

我不确定如何在没有链式分配的情况下执行此操作(这可能无论如何都行不通,因为我要设置一个副本)。

我不想获取多索引 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

但不知何故,我觉得有比遍历列更好的方法来做到这一点。在 pandas 中执行此操作的最佳方法是什么?

【问题讨论】:

    标签: python pandas multi-index


    【解决方案1】:

    这是 MultiIndex 切片器的一个应用程序(也是使用 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
    

    由于您正在使用第一级的列索引,因此以下内容也可以使用。上面的例子更笼统,假设你想为 'a' 做这个。

    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
    

    【讨论】:

    • 啊,好的,谢谢!使用切片器创建蒙版看起来非常有用(可能必须在我的更多代码中使用它)。第二个例子确实解决了我的具体问题。我不知道df['A']df[['A']] 之间的区别
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-02
    • 1970-01-01
    相关资源
    最近更新 更多