Pandas:SettingWithCopyWarning,试图了解如何更好地编写代码,而不仅仅是忽略警告

时间:2016-07-16 15:25:24

标签: python-2.7 pandas slice chained-assignment

我正在尝试将年份早于1900的电子表格日期列中的所有日期值更改为今天的日期,因此我有一个切片。

编辑:之前的代码行:

df=pd.read_excel(filename)#,usecols=['NAME','DATE','EMAIL']
#regex to remove weird characters
df['DATE'] = df['DATE'].str.replace(r'[^a-zA-Z0-9\._/-]', '')
df['DATE'] = pd.to_datetime(df['DATE'])

sample row in dataframe: name, date, email
[u'Public, Jane Q.\xa0' u'01/01/2016\xa0' u'jqpublic@email.com\xa0'] 

这行代码有效。

df["DATE"][df["DATE"].dt.year < 1900] = dt.datetime.today()

然后,所有日期值都被格式化:

df["DATE"] = df["DATE"].map(lambda x: x.strftime("%m/%d/%y"))

但是我收到了一个错误:

SettingWithCopyWarning:  A value is trying to be set on a copy of a
slice from a DataFrame

See the caveats in the documentation:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-

抗复制

我已阅读文档和其他帖子,建议使用.loc

以下是推荐的解决方案:

df.loc[row_indexer,col_indexer] = value

但是df["DATE"].loc[df["DATE"].dt.year < 1900] = dt.datetime.today()给了我同样的错误,除了行号实际上是脚本中最后一行之后的行号。

我只是不明白文档试图告诉我的内容,因为它与我的例子有关。

我开始搞砸了切片并分配到一个单独的数据帧,但是我必须再次将它们组合在一起。

2 个答案:

答案 0 :(得分:1)

我的想法是你可以做到

df.loc[df.DATE.dt.year < 1900, "DATE"] = dt.datetime.today()
df.loc[:, "DATE"] = df.DATE.map(lambda x: x.strftime("%m/%d/%y")

不在电脑上,所以我无法测试,但我认为应该这样做。

答案 1 :(得分:1)

您正在df["DATE"]生成视图,然后使用选择器[df["DATE"].dt.year < 1900]并尝试分配给它。

df["DATE"][df["DATE"].dt.year < 1900]是大熊猫抱怨的观点。

使用loc修复此问题:

df.loc[df.DATE.dt.year < 1900, "DATE"] = pd.datetime.today()