熊猫使用什么规则来生成一个视图和一个副本?

我对熊猫使用的规则感到困惑,当决定从一个数据框架选择是一个原始数据框架的副本,或原始视图。

举个例子,

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']

没有。

有没有一个简单的规则,熊猫正在使用,我只是缺少?在这些特定的情况下会发生什么; 特别是,如何更改数据框架中满足特定查询的所有值(或值的子集)(正如我在上面的示例中试图做的那样) ?


注意: 这和 这个问题不一样,我读过 文件,但是没有受到启发。我也通读了关于这个主题的“相关”问题,但我仍然没有看到熊猫使用的简单规则,以及我将如何应用它ーー例如ーー修改数据框架中满足特定查询的值(或值的子集)。

58114 次浏览

规则是这样的,后续重写:

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

  • 如果提供了 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']

因为这是 再快点,并将始终工作

链式索引是两个独立的 python 操作,因此熊猫无法可靠地拦截(您通常会得到一个 SettingWithCopyWarning,但这也不是100% 可检测的)。你指出的 开发文档提供了一个更加完整的解释。

有趣的是:

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

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