使用 Python pandas 数据框时返回副本与视图警告

Posted

技术标签:

【中文标题】使用 Python pandas 数据框时返回副本与视图警告【英文标题】:Returning a copy versus a view warning when using Python pandas dataframe 【发布时间】:2021-05-25 22:23:45 【问题描述】:

我的目的是将date列从日期框架df中的对象类型转换为日期时间类型,但在运行程序时遭受了很多查看和复制警告。

我从链接中找到了一些有用的信息:https://***.com/a/25254087/3849539

并测试了以下三种解决方案,它们都按预期工作,但警告消息不同。任何人都可以帮助解释他们的差异并指出为什么仍然警告消息返回视图而不是副本?谢谢。

解决方案 1:df['date'] = df['date'].astype('datetime64')

test.py:85: SettingWithCopyWarning: 试图在 从 DataFrame 复制切片。尝试使用 .loc[row_indexer,col_indexer] = 值 而是

请参阅文档中的注意事项: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy df['date'] = df['date'].astype('datetime64')

解决方案 2:df['date'] = pd.to_datetime(df['date'])

~/report/lib/python3.8/site-packages/pandas/core/frame.py:3188: SettingWithCopyWarning:试图在一个副本上设置一个值 从 DataFrame 切片。尝试使用 .loc[row_indexer,col_indexer] = 值 而是

请参阅文档中的注意事项: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy 自我[k1] = 价值[k2] test.py:85: SettingWithCopyWarning: 值是 试图在数据帧的切片副本上设置。尝试使用 .loc[row_indexer,col_indexer] = 值 而是

请参阅文档中的注意事项: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy

解决方案 3:df.loc[:, 'date'] = pd.to_datetime(df.loc[:, 'date'])

~/report/lib/python3.8/site-packages/pandas/core/indexing.py:1676: SettingWithCopyWarning:试图在一个副本上设置一个值 从 DataFrame 切片。尝试使用 .loc[row_indexer,col_indexer] = value 而是

请参阅文档中的注意事项: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy self._setitem_single_column(ilocs[0], value, pi)

【问题讨论】:

这能回答你的问题吗? How to deal with SettingWithCopyWarning in Pandas 【参考方案1】:

我最近收到了类似的警告。经过几次尝试,至少在我的情况下,问题与您的 3 个解决方案无关。它可能是你的“df”。

如果您的 df 是另一个 pandas df 的切片,例如:

df = dfOrigin[slice,:] or
df = dfOrigin[[some columns]] or
df = dfOrigin[one column]

然后,如果您对 df 执行任何操作,就会出现该警告。尝试改用df = dfOrigin[[]].copy()

重现此的代码:

import numpy as np
import pandas as pd
np.random.seed(2021)
dfOrigin = pd.DataFrame(np.random.choice(10, (4, 3)), columns=list('ABC'))
print("Orignal dfOrigin")
print(dfOrigin)
#    A  B  C
# 0  4  5  9
# 1  0  6  5
# 2  8  6  6
# 3  6  6  1
df = dfOrigin[['B', 'C']]  # Returns a view
df.loc[:,'B'] = df['B'].astype(str) #Get SettingWithCopyWarning

df2 = dfOrigin[['B', 'C']].copy() #Returns a copy
df2['B'] = df2['B'].astype(str) #OK

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。【参考方案2】:

更改日期时间转换的方式不会修复SettingWithCopyWarning。你得到它是因为你正在使用的df 已经是一些更大的数据帧的一部分。 Pandas 只是警告您正在使用切片而不是完整数据。请尝试在 df 中创建一个新列 - 您会收到警告,但该列将存在于您的切片中。它不会在原始数据集中。

如果你现在正在做什么,你可以使用pd.options.mode.chained_assignment = None # default='warn'关闭这些警告

【讨论】:

您好 Darina,感谢您的回答。根据您的信息,如果我想在原始数据而不是切片上创建一个新列,我应该怎么做?谢谢。 那么不要使用df,而是使用它来自的原始数据框。顺便说一句,在某些时候你可能会做类似df = df[df.column==condition] 的事情——这也会创建一个切片(并覆盖原始的df 值)。如果你我的回答对你有帮助,你能接受它是正确的吗?

以上是关于使用 Python pandas 数据框时返回副本与视图警告的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Python 用后来调整的副本替换早期定义的 Pandas 数据框? [复制]

pandas query

Python Pandas SettingWithCopyWarning 副本与新对象

使用 Pandas 在 Python 中过滤嵌套的 JSON 数据

将dict保存为pandas数据框时如何保持排序?

使用 pandas Python (pandas.io.parsers.TextFileReader) 从文件中读取数据时出现问题