Pandas 使用啥规则来生成视图和副本?
Posted
技术标签:
【中文标题】Pandas 使用啥规则来生成视图和副本?【英文标题】:What rules does Pandas use to generate a view vs a copy?Pandas 使用什么规则来生成视图和副本? 【发布时间】:2014-06-11 08:30:46 【问题描述】:我对 Pandas 在确定数据框中的选择是原始数据框的副本还是原始数据框的视图时使用的规则感到困惑。
如果我有,例如,
df = pd.DataFrame(np.random.randn(8,8), columns=list('ABCDEFGH'), index=range(1,9))
我知道 query
返回一个副本,以便类似
foo = df.query('2 < index <= 5')
foo.loc[:,'E'] = 40
对原始数据帧df
没有影响。我也明白标量或命名切片返回一个视图,以便对这些进行分配,例如
df.iloc[3] = 70
或
df.ix[1,'B':'E'] = 222
将更改df
。但是当涉及到更复杂的情况时,我会迷路。例如,
df[df.C <= df.B] = 7654321
更改df
,但是
df[df.C <= df.B].ix[:,'B':'E']
没有。
Pandas 是否有一个我只是缺少的简单规则?在这些特定情况下发生了什么;特别是,如何更改满足特定查询的数据框中的所有值(或值的子集)(正如我在上面的最后一个示例中尝试做的那样)?
注意:这和this question不一样;我读过the documentation,但没有被它启发。我还通读了关于这个主题的“相关”问题,但我仍然错过了 Pandas 使用的简单规则,以及我将如何应用它——例如——修改值(或值的子集)在满足特定查询的数据框中。
【问题讨论】:
【参考方案1】:这是规则,后续覆盖:
所有操作都会生成一个副本
如果提供了inplace=True
,它将就地修改;只有部分操作支持这个
设置的索引器,例如.loc/.iloc/.iat/.at
将就地设置。
获取单一类型对象的索引器几乎总是一个视图(取决于内存布局,这可能不是这不可靠的原因)。这主要是为了效率。 (上面的示例是针对 .query
的;这将始终返回由 numexpr
评估的副本)
获取多类型对象的索引器始终是副本。
chained indexing
的例子
df[df.C <= df.B].loc[:,'B':'E']
不能保证有效(因此您应该永远不要这样做)。
改为:
df.loc[df.C <= df.B, 'B':'E']
因为这是 更快 并且将始终有效
链式索引是 2 个独立的 python 操作,因此不能被 pandas 可靠地拦截(您经常会得到一个SettingWithCopyWarning
,但这也不是 100% 可检测到的)。您指出的dev docs 提供了更完整的解释。
【讨论】:
.query
总是会返回一个副本,因为它在做什么(而不是视图),因为它由 n numexpr 评估。所以我会把它添加到“规则”中
pandas 依赖 numpy 来确定是否生成视图。在单个 dtype 的情况下(可能是系列的 1-d,帧的 2-d 等)。 numpy 可能生成视图;这取决于您要切片的内容;有时你可以看到,有时你不能。 pandas 根本不依赖这个事实,因为是否生成视图并不总是很明显。但这并不重要,因为 loc 在设置时不依赖于此。但是,当链索引时,这非常重要(因此为什么链索引不好)
非常感谢 Jeff,您的回复非常有用。您对此主题的来源/参考资料是什么?
那么首先,感谢您的出色工作!其次,如果您有足够的时间,我认为在文档中添加类似于您的主要回复的段落会很棒。
当然会接受拉取请求来添加/修改文档。去吧。【参考方案2】:
这里有一些有趣的事情:
u = df
v = df.loc[:, :]
w = df.iloc[:,:]
z = df.iloc[0:, ]
前三个好像都是df的引用,最后一个不是!
【讨论】:
正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。以上是关于Pandas 使用啥规则来生成视图和副本?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Python pandas 数据框时返回副本与视图警告