试图在 DataFrame 中的切片副本上设置一个值

Posted

技术标签:

【中文标题】试图在 DataFrame 中的切片副本上设置一个值【英文标题】:A value is trying to be set on a copy of a slice from a DataFrame 【发布时间】:2016-08-24 00:48:12 【问题描述】:

我有一个数据框列期间,它的值按季度(Q1、Q2、Q3、Q4)计算,我想将其转换为相关月份(请参阅 dict)。我下面的代码可以正常工作,但想知道为什么我会收到此警告。

试图在 DataFrame 中的切片副本上设置值。 尝试改用 .loc[row_indexer,col_indexer] = value

quarter = "Q1":"Mar","Q2":"Jun","Q3":"Sep","Q4":"Dec"
df['period'] = df['period'].astype(str).map(quarter)

【问题讨论】:

【参考方案1】:

“试图在来自 DataFrame 的切片副本上设置值”是一个警告。 SO 包含许多关于此主题的帖子。

df.assign 是在 Pandas 0.16 中添加的,是避免此警告的好方法。

quarter = "Q1": "Mar", "Q2": "Jun", "Q3": "Sep", "Q4": "Dec"
df = pd.DataFrame('period': ['Q1', 'Q2', 'Q3', 'Q4', 'Q5'], 'qtr': [1, 2, 3, 4, 5])

df
  period  qtr
0     Q1    1
1     Q2    2
2     Q3    3
3     Q4    4
4     Q5    5

df = df.assign(period=[quarter.get(q, q) for q in df.period])

# Unmapped values unchanged.
>>> df
  period  qtr
0    Mar    1
1    Jun    2
2    Sep    3
3    Dec    4
4     Q5    5

df = pd.DataFrame('period': ['Q1', 'Q2', 'Q3', 'Q4', 'Q5'], 'qtr': [1, 2, 3, 4, 5])
df = df.assign(period=df.period.map(quarter))

# Unmapped values get `NaN`.
>>> df
  period  qtr
0    Mar    1
1    Jun    2
2    Sep    3
3    Dec    4
4    NaN    5

将新列分配给 DataFrame,返回一个新对象 (副本)除了新列之外的所有原始列。

.. 版本添加:: 0.16.0

【讨论】:

我认为在早期版本中,有时会错误地显示警告。我在 pandas 0.18.0 中没有收到警告。但是很高兴了解assign。 这个答案非常适合。与触发此错误的其他情况相比,此错误没有过滤步骤。当您链接多个操作以创建一个新计算的列时,这个非常适用。 如果我想就地添加一列怎么办?例如,当在 DataFrame 列表上的方法内迭代时,我希望将更改就地应用于输入列表。语法 df['new_col'] = pd.Series(some_vals) 可以按我的意愿工作,但我仍然收到此警告【参考方案2】:

您正在使用切片的 Pandas 数据框。

最好的办法是尝试切片数据的深层副本,而不是原始切片。这将确保Chained Indexing 不会发生

df['period'] = df.loc['period'].astype(str).copy().map(quarter)

【讨论】:

以上是关于试图在 DataFrame 中的切片副本上设置一个值的主要内容,如果未能解决你的问题,请参考以下文章

Pandas SettingWithCopyWarning:试图在 DataFrame 中的切片副本上设置值

Pandas DataFrame:SettingWithCopyWarning:试图在 DataFrame 的切片副本上设置一个值 [重复]

对于使用 Dask 的 Series 对象,“试图在来自 DataFrame 的切片的副本上设置一个值”?

熊猫“试图在数据帧的切片副本上设置一个值”

在数据帧的切片副本上设置值[重复]

将 Pandas DataFrame 切片成新的 DataFrame