157

当决定从数据框中选择的内容是原始数据框的副本或原始数据框的视图时,我对 Pandas 使用的规则感到困惑。

例如,如果我有,

df = pd.DataFrame(np.random.randn(8,8), columns=list('ABCDEFGH'), index=range(1,9))

我知道 aquery返回一个副本,以便类似

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 是否有一个我只是缺少的简单规则?在这些特定情况下发生了什么;特别是,如何更改满足特定查询的数据框中的所有值(或值的子集)(正如我在上面的最后一个示例中尝试做的那样)?


注意:这与这个问题不同;我已经阅读了文档,但没有受到启发。我还通读了关于这个主题的“相关”问题,但我仍然错过了 Pandas 使用的简单规则,以及我如何将其应用于——例如——修改值(或值的子集)在满足特定查询的数据框中。

4

2 回答 2

171

这是规则,后续覆盖:

  • 所有操作都生成一个副本

  • 如果inplace=True提供,它将就地修改;只有一些操作支持这一点

  • 设置的索引器,例如.loc/.iloc/.iat/.at将就地设置。

  • 获取单一类型对象的索引器几乎总是一个视图(取决于内存布局,这可能不是这不可靠的原因)。这主要是为了效率。(上面的例子是 for .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提供了更完整的解释。

于 2014-04-25T14:57:14.193 回答
0

这里有一些有趣的事情:

u = df
v = df.loc[:, :]
w = df.iloc[:,:]
z = df.iloc[0:, ]

前三个似乎都是df的引用,但最后一个不是!

于 2021-10-07T06:11:14.627 回答