【问题标题】:Pandas: Cannot assign NaN using a boolean mask on MultiIndex columnsPandas:无法在 MultiIndex 列上使用布尔掩码分配 NaN
【发布时间】:2017-03-16 13:28:21
【问题描述】:

首先,创建这个 DataFrame:

df = pd.DataFrame([[1,-2,3],[4,5,-6],[-7,8,9]],
    columns=pd.MultiIndex.from_tuples(
        [('foo', 'bar'), ('foo', 'baz'), ('ignore', 'other')]))

即:

  foo     ignore
  bar baz  other
0   1  -2      3
1   4   5     -6
2  -7   8      9

现在,尝试用 NAN 替换 foo 下的负值:

df.foo[df.foo < 0] = np.nan

除了打印警告之外什么都不做:

SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

好的,让我们这样做:

df.loc[:,'foo'][df.foo < 0] = np.nan

这不会打印警告,但它也什么都不做!

但如果我们使用非 NAN 值,它会起作用:

df.loc[:,'foo'][df.foo < 0] = 666

现在我有:

   foo      ignore
   bar  baz  other
0    1  666      3
1    4    5     -6
2  666    8      9

但我想填写 NAN,而不是 666。有什么简单的方法可行吗?

【问题讨论】:

    标签: pandas slice nan hierarchical-data


    【解决方案1】:

    您可以将slicersDataFrame.mask 一起使用:

    idx = pd.IndexSlice
    sliced = df.loc[:, idx['foo',:]]
    print (sliced)
      foo    
      bar baz
    0   1  -2
    1   4   5
    2  -7   8
    
    df.loc[:, idx['foo',:]] = sliced.mask(sliced < 0)
    print (df) 
       foo      ignore
       bar  baz  other
    0  1.0  NaN      3
    1  4.0  5.0     -6
    2  NaN  8.0      9
    

    concat 的另一个解决方案:

    idx = pd.IndexSlice
    df1 = df.loc[:, idx['foo',:]]
    print (df1)
      foo    
      bar baz
    0   1  -2
    1   4   5
    2  -7   8
    
    df1 = df1.mask(df1 < 0)
    print (df1) 
       foo     
       bar  baz
    0  1.0  NaN
    1  4.0  5.0
    2  NaN  8.0
    
    print (pd.concat([df1, df.drop('foo', axis=1, level=0)], axis=1))
       foo      ignore
       bar  baz  other
    0  1.0  NaN      3
    1  4.0  5.0     -6
    2  NaN  8.0      9
    

    【讨论】:

    • 这段代码确实有效,但它丑陋且效率低下(不是你的错!)。它必须复制整个foo 两次!
    • 我觉得MultiIndex有点复杂,我尝试添加另一个解决方案并重写旧的。
    • 很遗憾sliced = sliced.mask(sliced&lt;0, np.nan) 不起作用,需要分配给切片数据帧。
    猜你喜欢
    • 2021-10-11
    • 2013-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-23
    • 1970-01-01
    • 2017-11-10
    • 1970-01-01
    相关资源
    最近更新 更多