gpt4 book ai didi

python - pandas dataframe view vs copy,我怎么知道?

转载 作者:太空狗 更新时间:2023-10-29 17:26:12 25 4
gpt4 key购买 nike

有什么区别:

Pandas df.loc[:,('col_a','col_b')]

df.loc[:,['col_a','col_b']]

下面的链接没有提到后者,尽管它有效。两者都拉一个 View 吗?第一个拉 View ,第二个拉副本吗?喜欢学习 Pandas。

http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy

谢谢

最佳答案

如果你的 DataFrame 有一个简单的列索引,那么就没有区别。例如,

In [8]: df = pd.DataFrame(np.arange(12).reshape(4,3), columns=list('ABC'))

In [9]: df.loc[:, ['A','B']]
Out[9]:
A B
0 0 1
1 3 4
2 6 7
3 9 10

In [10]: df.loc[:, ('A','B')]
Out[10]:
A B
0 0 1
1 3 4
2 6 7
3 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 5

In [27]: df.loc[:, ('foo','B')]
Out[27]:
baz C 9
D 5
qux C 0
D 7
C 4
Name: (foo, B), dtype: int64

In [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 5
qux C 0
D 7
C 4
Name: (foo, B), dtype: int64

In [30]: df.sortlevel(axis=1).loc[:, ['foo','B']]
Out[30]:
foo
A B
baz C 7 9
D 7 5
qux 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可能会返回副本或 View 。 Pandas 文档没有指定任何您应该期望的规则。但是,如果您对表单进行赋值

df.loc[...] = value

那么你可以信任 Pandas 来改变 df本身。

文档之所以警告 View 和副本之间的区别,是为了让您意识到使用表单链赋值的陷阱

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

在这里,Pandas 评估 df.loc[...]首先,它可能是 View 或副本。现在如果是副本,那么

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

正在更改 df 的某些部分的副本,因此对 df 没有影响本身。雪上加霜的是,对副本的影响也丢失了,因为没有对副本的引用,因此在赋值语句完成后无法访问副本,并且(至少在 CPython 中)因此很快- 将被垃圾收集。


我不知道有什么实用的万无一失的先验方法来确定df.loc[...]将返回 View 或副本。

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

  • 如果生成的 NDFrame 不能表示为底层 NumPy 数组,那么它可能是一个副本。因此,选择任意行或列将导致复制。选择连续的行和/或连续的列(可以表示为切片)可能会返回一个 View 。
  • 如果生成的 NDFrame 具有不同数据类型的列,则 df.loc可能会再次返回副本。

但是,有一种简单的方法可以确定 x = df.loc[..] 是否存在。是一个 View a postiori:只需查看是否更改 x 中的值影响 df .如果是,它是一个 View ,如果不是,x是副本。

关于python - pandas dataframe view vs copy,我怎么知道?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27367442/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com