栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

pandas数据框视图vs复制,我怎么知道?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

pandas数据框视图vs复制,我怎么知道?

如果您的Dataframe具有简单的列索引,则没有区别。例如,

In [8]: df = pd.Dataframe(np.arange(12).reshape(4,3), columns=list('ABC'))In [9]: df.loc[:, ['A','B']]Out[9]:    A   B0  0   11  3   42  6   73  9  10In [10]: df.loc[:, ('A','B')]Out[10]:    A   B0  0   11  3   42  6   73  9  10

但是,如果Dataframe具有MultiIndex,则可能会有很大的不同:

df = pd.Dataframe(np.random.randint(10, size=(5,4)),       columns=pd.MultiIndex.from_arrays([['foo']*2+['bar']*2,         list('ABAB')]),       index=pd.MultiIndex.from_arrays([['baz']*2+['qux']*3,       list('CDCDC')]))#       foo    bar   #         A  B   A  B# baz C   7  9   9  9#     D   7  5   5  4# qux C   5  0   5  1#     D   1  7   7  4#     C   6  4   3  5In [27]: df.loc[:, ('foo','B')]Out[27]: baz  C    9     D    5qux  C    0     D    7     C    4Name: (foo, B), dtype: int64In [28]: df.loc[:, ['foo','B']]KeyError: 'MultiIndex Slicing requires the index to be fully lexsorted tuple len (1), lexsort depth (0)'

KeyError表示必须对MultiIndex进行排序。如果我们这样做,那么我们仍然会得到不同的结果:

In [29]: df.sortlevel(axis=1).loc[:, ('foo','B')]Out[29]: baz  C    9     D    5qux  C    0     D    7     C    4Name: (foo, B), dtype: int64In [30]: df.sortlevel(axis=1).loc[:, ['foo','B']]Out[30]:       fooA  Bbaz C   7  9    D   7  5qux C   5  0    D   1  7    C   6  4

这是为什么?

df.sortlevel(axis=1).loc[:, ('foo','B')]
正在选择第一列级别等于
foo
,第二列级别等于的列
B

相反,

df.sortlevel(axis=1).loc[:,['foo','B']]
正在选择第一列级别为
foo
或的列
B
。关于第一列级别,没有
B
列,但是有两
foo
列。

我认为Pandas的操作原理是,如果您将其

df.loc[...]
用作 表达式
,则应假定
df.loc
可能正在返回副本或视图。Pandas文档未指定您应该遵循的任何规则。但是,如果您 分配 表格

df.loc[...] = value

那么您可以信任熊猫来改变

df
自己。

该文档之所以警告有关视图和副本之间的区别的原因,是为了使您意识到使用以下形式的链分配的陷阱

df.loc[...][...] = value

在这里,Pandas

df.loc[...]
首先评估,它可以是视图或副本。现在,如果它是副本,则

df.loc[...][...] = value

正在更改的某些部分的副本

df
,因此对其
df
自身没有影响。更糟的是,由于没有引用副本,因此对副本的影响也会丢失,因此在赋值语句完成后就无法访问副本,因此(至少在CPython中)垃圾收集。


我不知道一种实用 的先验 方法来确定是否

df.loc[...]
要返回视图或副本。

但是,有一些经验法则可能有助于指导您的直觉(但是请注意,我们在这里讨论实现细节,因此不能保证熊猫将来会以这种方式行事):

  • 如果结果NDframe无法表示为基础NumPy数组的基本切片,则它可能是一个副本。因此,选择任意的行或列将导致复制。选择顺序行和/或顺序列(可以表示为切片)可以返回视图。
  • 如果结果NDframe具有不同dtypes的列,则
    df.loc
    可能会再次返回一个副本。

然而,有一个简单的方法来确定是否

x = df.loc[..]
是一个视图 一个postiori
:只需看看是否改变值
x
影响
df
。如果是,则为视图,否则
x
为副本。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/633708.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号