当列是现有列的布尔测试时,为啥向 Pandas DataFrame 添加列会返回 SettingWithCopy 警告?

Posted

技术标签:

【中文标题】当列是现有列的布尔测试时,为啥向 Pandas DataFrame 添加列会返回 SettingWithCopy 警告?【英文标题】:Why does adding a column to a Pandas DataFrame return a SettingWithCopy warning when the column is a boolean test of an existing column?当列是现有列的布尔测试时,为什么向 Pandas DataFrame 添加列会返回 SettingWithCopy 警告? 【发布时间】:2015-10-21 06:20:45 【问题描述】:

我在现有的SettingWithCopy 警告问题中找不到答案,因为常见的.loc 解决方案似乎并不适用。我正在将一个表加载到熊猫中,然后尝试根据其他列中的值创建一些掩码列。出于某种原因,即使我将测试包装在pd.Series 构造函数中,这也会返回SettingWithCopy 警告。

这是相关代码。最后的输出似乎是正确的,但有谁知道这是什么原因造成的?

all_invs = pd.read_table('all_quads.inv.bed', index_col=False,
                         header=None, names=clustered_names)

invs = all_invs[all_invs['uniqueIDs'].str.contains('p1')]
samples = [line.strip() for line in open('success_samples.list')]

for sample in samples:
    invs[sample] = invs['uniqueIDs'].str.contains(sample)

另一个布尔测试也会发生这种情况。

invs["%s_private_denovo" % proband] = pd.Series(
    invs[proband] & ~invs[father] & ~invs[mother] &
    invs["%s_private" % proband])

谢谢!

【问题讨论】:

Setting values on a copy of a slice from a DataFrame 的可能重复项 【参考方案1】:

我猜invs 会导致警告。要解决这个问题,请像这样显式复制它:

invs = all_invs[all_invs['uniqueIDs'].str.contains('p1')].copy()

【讨论】:

【参考方案2】:

这是来自this post 的所选答案的副本。

出现此警告是因为您的数据框 x 是切片的副本。这并不容易知道原因,但它与您如何进入当前状态有关。

您可以通过执行从 x 中创建适当的数据框

x = x.copy()

这将删除警告,但这不是正确的方法

您应该使用DataFrame.loc 方法,如警告所示,如下所示:

x.loc[:,'Mass32s'] = pandas.rolling_mean(x.Mass32, 5).shift(-2)

【讨论】:

以上是关于当列是现有列的布尔测试时,为啥向 Pandas DataFrame 添加列会返回 SettingWithCopy 警告?的主要内容,如果未能解决你的问题,请参考以下文章

当列是 JSON 数组而不是字符串时如何过滤 ANTD 表

Scala(Spark)-当列是列表时如何分组

PySpark:当列是列表时,将列添加到 DataFrame

当列是整数和小数的混合时,创建表时使用哪种数据类型?

Pandas:创建字典,其中一列是键,其余列的列表是值

当列是NTEXT时,SQL Server:IN('asd')不工作