【发布时间】:2018-06-18 19:55:06
【问题描述】:
我喜欢 pandas 并且已经使用了多年,并且我非常有信心我能够很好地处理如何对数据帧进行子集化以及适当地处理视图与副本(尽管我使用了很多断言来确定)。我也知道有很多关于 SettingWithCopyWarning 的问题,例如How to deal with SettingWithCopyWarning in Pandas? 以及最近一些很棒的指南,可以在发生这种情况时将头缠住,例如Understanding SettingWithCopyWarning in pandas。
但我也知道诸如 this answer 的引用之类的具体内容不再出现在最新的文档 (0.22.0) 中,并且多年来许多内容已被弃用(导致一些不恰当的旧 SO 答案),并且那东西是continuing to change。
最近在教 pandas 完成新手学习非常基本的 Python 知识后,例如避免链式索引(并使用 .iloc/.loc),我仍然难以提供一般经验法则 知道什么时候注意SettingWithCopyWarning 很重要(例如,什么时候可以安全地忽略它)。
我个人发现,根据某些规则(例如切片或布尔运算)对数据帧进行子集化然后修改该子集的特定模式,独立于原始数据帧比文档建议的常见操作。在这种情况下,我们希望修改副本而不是原件,并且警告会让新手感到困惑/害怕。
我知道提前知道何时返回视图与副本并非易事,例如
What rules does Pandas use to generate a view vs a copy?
Checking whether data frame is copy or view in Pandas
因此,我正在寻找更一般(初学者友好)问题的答案:何时对子集数据帧执行操作会影响创建它的原始数据帧,它们何时独立? 。
我在下面创建了一些我认为合理的案例,但我不确定我是否遗漏了“陷阱”,或者是否有任何更简单的方法来思考/检查这一点。我希望有人可以确认我对以下用例的直觉与我上面的问题有关。
import pandas as pd
df1 = pd.DataFrame({'A':[2,4,6,8,10],'B':[1,3,5,7,9],'C':[10,20,30,40,50]})
1) 警告:否
原始更改:否
# df1 will be unaffected because we use .copy() method explicitly
df2 = df1.copy()
#
# Reference: docs
df2.iloc[0,1] = 100
2) 警告:是的(我不太明白为什么)
原始更改:否
# df1 will be unaffected because .query() always returns a copy
#
# Reference:
# https://stackoverflow.com/a/23296545/8022335
df2 = df1.query('A < 10')
df2.iloc[0,1] = 100
3) 警告:是
原始更改:否
# df1 will be unaffected because boolean indexing with .loc
# always returns a copy
#
# Reference:
# https://stackoverflow.com/a/17961468/8022335
df2 = df1.loc[df1['A'] < 10,:]
df2.iloc[0,1] = 100
4) 警告:否
原始更改:否
# df1 will be unaffected because list indexing with .loc (or .iloc)
# always returns a copy
#
# Reference:
# Same as 4)
df2 = df1.loc[[0,3,4],:]
df2.iloc[0,1] = 100
5) 警告:否
原作改动:是(让新手感到困惑,但有道理)
# df1 will be affected because scalar/slice indexing with .iloc/.loc
# always references the original dataframe, but may sometimes
# provide a view and sometimes provide a copy
#
# Reference: docs
df2 = df1.loc[:10,:]
df2.iloc[0,1] = 100
tl;博士
从原始数据框创建新数据框时,更改新数据框:
当标量/切片索引与 .loc/.iloc 用于创建新数据帧时,将更改原始数据。
不会在使用 .loc、.query() 或 .copy() 的布尔索引创建新数据框时更改原始索引
【问题讨论】:
-
嗯,最近,related question
-
我总是使用#3,我讨厌这个警告
标签: python pandas views chained-assignment