【问题标题】:Why do I get a SettingWithCopyWarning when using a MultiIndex (but not with a simple index)?为什么在使用 MultiIndex(但不是简单索引)时会出现 SettingWithCopyWarning?
【发布时间】:2023-01-24 18:49:46
【问题描述】:

以下代码按预期工作,没有任何警告。我创建了一个数据框,使用 .loc 从中创建了两个子数据框,给它们相同的索引,然后分配给其中一个的列。

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.randn(20, 4),
                  index=pd.Index(range(20)),
                  columns=['one', 'two', 'three', 'four'])

d1 = df.loc[[2, 4, 6], :]
d2 = df.loc[[3, 5, 7], :]

idx = pd.Index(list('abc'), name='foo')
d1.index = idx
d2.index = idx

d1['one'] = d1['one'] - d2['two']

但是,如果我做完全相同的事情,除了多索引数据框,我会得到一个SettingWithCopyWarning

import numpy as np
import pandas as pd

arrays = [
    np.array(["bar", "bar", "baz", "baz", "foo", "foo", "qux", "qux"]),
    np.array(["one", "two", "one", "two", "one", "two", "one", "two"]),
]
df = pd.DataFrame(np.random.randn(8, 4), index=arrays, columns=['one', 'two', 'three', 'four'])

d1 = df.loc[(['bar', 'qux', 'foo'], 'one'), :]
d2 = df.loc[(['bar', 'qux', 'foo'], 'two'), :]

idx = pd.Index(list('abc'), name='foo')
d1.index = idx
d2.index = idx

d1['one'] = d1['one'] - d2['two']

我知道我可以通过在创建 df1df2 期间使用 .copy() 来避免此警告,但我很难理解为什么这在第二种情况下是必要的,但在第一种情况下不是。链式索引在这两种情况下同样存在,不是吗?那么,有什么区别呢?

【问题讨论】:

    标签: python pandas dataframe multi-index chained-assignment


    【解决方案1】:

    您必须使用 set_index 来避免警告:

    import numpy as np
    import pandas as pd
    
    arrays = [
        np.array(["bar", "bar", "baz", "baz", "foo", "foo", "qux", "qux"]),
        np.array(["one", "two", "one", "two", "one", "two", "one", "two"]),
    ]
    df = pd.DataFrame(np.random.randn(8, 4), index=arrays, columns=['one', 'two', 'three', 'four'])
    
    d1 = df.loc[(['bar', 'qux', 'foo'], 'one'), :]
    d2 = df.loc[(['bar', 'qux', 'foo'], 'two'), :]
    
    idx = pd.Index(list('abc'), name='foo')
    d1 = d1.set_index(idx)  # <- HERE
    d2 = d2.set_index(idx)  # <- HERE
    
    d1['one'] = d1['one'] - d2['two']
    

    【讨论】:

      猜你喜欢
      • 2020-10-04
      • 2022-01-26
      • 1970-01-01
      • 2017-08-26
      • 1970-01-01
      • 2013-10-30
      • 2019-06-02
      • 2019-05-17
      • 1970-01-01
      相关资源
      最近更新 更多