如何在不生成 SettingWithCopyWarning 的情况下将列插入 DataFrame
Posted
技术标签:
【中文标题】如何在不生成 SettingWithCopyWarning 的情况下将列插入 DataFrame【英文标题】:How to insert a column into a DataFrame without generating the SettingWithCopyWarning 【发布时间】:2018-05-02 11:29:53 【问题描述】:我想在现有的 DataFrame 中插入一列。理想情况下不复制现有数据。无论我尝试什么,如果插入的数据包含空值,以后对结果 DataFrame 的分配都会生成一个 SettingWithCopyWarning。
import pandas as pd
df = pd.DataFrame(data='a': [1])
df = df.assign(b=pd.Series(data=pd.NaT, index=df.index))
df['a'].iloc[0] = 5
将assign
替换为
df['b'] = pd.Series(data=pd.NaT, index=df.index)
df.insert(column='b', loc=0, value=pd.NaT)
导致相同的警告。
很奇怪,如果插入的值不为空(例如,用 0 替换 pd.NaT)不会产生警告。这是一个错误吗?
【问题讨论】:
【参考方案1】:您的问题似乎与df['a'].iloc[0] = 5
相关,您使用的是chained assignment。试试这个:
df.at[0, 'a'] = 5
# Or: df.loc[0, 'a'] = 5, but `.at` is preferred when assigning scalar
【讨论】:
很奇怪,如果我将空值替换为非空值,则不会生成警告。这就是为什么我认为这个链式分配应该可以正常工作。另外,我想对行使用基于位置的选择,对列使用基于标签的选择,这不适用于at
、loc
、iat
或iloc
,AFAIK。并且 ix
已弃用。
@Konstantin,用于混合(位置+标签)索引使用:df.loc[df.index[position], 'column_name']
是的,关于.ix
和结合基于位置/标签的索引:这可能看起来不方便,但.ix
已被弃用特别是出于这个原因。开发人员希望尽可能避免歧义——例如,如果您的索引是 [1, 0] 并且您使用了.ix
,这应该指的是位置还是标签?
@MaxU:是的,我意识到这种可能性,但发现它很难看。 df[column_name].iloc[position]
更直观。但似乎df.loc[df.index[position], 'column_name']
是避免警告的唯一方法。以上是关于如何在不生成 SettingWithCopyWarning 的情况下将列插入 DataFrame的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 Ruby 保存到磁盘的情况下生成 zip 文件?
如何在不创建数组的情况下使用 NgFor 来生成矩阵 UI 模式