Pandas使用什么规则来生成视图和副本?

oro*_*ome 98 python indexing dataframe pandas chained-assignment

我对Pandas在决定数据帧中的选择是原始数据帧的副本还是原始数据的视图时使用的规则感到困惑.

如果我有,例如,

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

我明白a query返回一个副本,就像这样

foo = df.query('2 < index <= 5')
foo.loc[:,'E'] = 40
Run Code Online (Sandbox Code Playgroud)

对原始数据帧没有影响df.我也理解标量或命名切片返回一个视图,以便分配给这些,例如

df.iloc[3] = 70
Run Code Online (Sandbox Code Playgroud)

要么

df.ix[1,'B':'E'] = 222
Run Code Online (Sandbox Code Playgroud)

会改变df.但是当谈到更复杂的案件时,我迷失了方向.例如,

df[df.C <= df.B]  = 7654321
Run Code Online (Sandbox Code Playgroud)

变化df,但是

df[df.C <= df.B].ix[:,'B':'E']
Run Code Online (Sandbox Code Playgroud)

才不是.

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


注意:这与此问题不同 ; 我已经阅读了文档,但没有得到它的启发.我还阅读了关于这个主题的"相关"问题,但我仍然缺少Pandas正在使用的简单规则,以及我如何应用它 - 例如 - 修改值(或值的子集)在满足特定查询的数据框中.

Jef*_*eff 117

这是规则,后续覆盖:

  • 所有操作都会生成副本

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

  • 设置的索引器,例如.loc/.iloc/.iat/.at将设置到位.

  • 获取单个dtyped对象的索引器几乎总是一个视图(取决于内存布局,它可能不是这就是为什么这不可靠).这主要是为了提高效率.(上面的示例是for .query;这将始终返回一个副本作为其评估者numexpr)

  • 获取多重对象对象的索引器始终是副本.

你的榜样 chained indexing

df[df.C <= df.B].loc[:,'B':'E']
Run Code Online (Sandbox Code Playgroud)

不能保证工作(因此你绝不会这样做).

相反:

df.loc[df.C <= df.B, 'B':'E']
Run Code Online (Sandbox Code Playgroud)

因为这更快,并将始终有效

链式索引是2个独立的python操作,因此不能被pandas可靠地拦截(你经常会得到一个SettingWithCopyWarning,但这也不是100%可检测的).您指出的开发文档提供了更全面的解释.

  • 我的来源是我编写了代码和文档. (111认同)
  • 首先,感谢您的出色工作!第二,如果你有足够的时间,我认为在文档中添加类似于主回复的段落会很棒. (4认同)
  • pandas依赖于numpy来确定是否生成了视图.在单个dtype情况下(对于一个系列可以是1-d,对于帧可以是2-d).numpy*may*生成一个视图; 这取决于你正在切片的东西; 有时你可以得到一个观点,有时你不能.大熊猫完全不依赖于这个事实,因为视图是否生成并不总是很明显.但这并不重要,因为loc在设置时不依赖于此.但是,当链索引时这非常重要(因此链索引的原因很糟糕) (3认同)
  • 非常感谢杰夫,你的回复最有用.您对此主题的来源/参考是什么? (3认同)
  • ``.query``总是会因为它在做什么(而不是视图)而返回一个副本,因为它是由n numexpr求值的。所以我将其添加到“规则”中 (2认同)
  • 肯定会采取拉动请求来添加/修改文档.去吧. (2认同)