数据帧视图或副本的好处是什么?

时间:2016-09-12 17:43:29

标签: python pandas chained-assignment

我已经看到很多关于臭名昭着的SettingWithCopy警告的问题。我甚至冒险回答其中的一些问题。最近,我正在整理一个涉及这个主题的答案,我想展示数据框视图的好处。我未能提供一个明确的证据,说明为什么创建数据框视图或生成{(1}}

的任何内容是个好主意。

考虑SettingWithCopy

df

df = pd.DataFrame([[1, 2], [3, 4]], list('ab'), list('AB')) df A B x 1 2 y 3 4 这是dfv

的副本
df
dfv = df[['A']]
print(dfv.is_copy)

<weakref at 0000000010916E08; to 'DataFrame' at 000000000EBF95C0>

我可以生成print(bool(dfv.is_copy)) True

SettingWithCopy

enter image description here

但是,dfv.iloc[0, 0] = 0 已更改

dfv

print(dfv) A a 0 b 3 没有

df

print(df) A B x 1 2 y 3 4 仍然是副本

dfv

如果我更改print(bool(dfv.is_copy)) True

df

但是df.iloc[0, 0] = 7 print(df) A B x 7 2 y 3 4 没有改变。不过,我可以参考dfv

中的df
dfv

问题

如果print(dfv.is_copy()) A B x 7 2 y 3 4 维护它自己的数据(意思是,它实际上不会节省内存)并且它通过赋值操作分配值,尽管有警告,那么为什么我们首先要保存引用并生成{{1在所有?

有什么好处?

1 个答案:

答案 0 :(得分:3)

有很多关于此的讨论,例如here,包括尝试过的PR。值得注意的是,视图的真正写时复制被认为是&#34; pandas 2.0&#34;重构,请参阅here

在您的示例中维护引用的原因是因为它一个视图,所以如果有人试图这样做,他们会收到警告。

df[['A']].iloc[0, 0] = 1

编辑:

就&#34;为什么要使用观点,&#34;它是出于性能/内存的原因。考虑一下,基本索引(选择列),因为此操作采用视图,几乎是瞬时的。

df = pd.DataFrame(np.random.randn(1000000, 2), columns=['a','b'])

%timeit df['a']
100000 loops, best of 3: 2.13 µs per loop

获取副本具有非常重要的成本。

%timeit df['a'].copy()
100 loops, best of 3: 4.28 ms per loop

此性能成本会显示在许多操作中,例如将两个Series加在一起。

%timeit df['a'] + df['b']
100 loops, best of 3: 4.31 ms per loop

%timeit df['a'].copy() + df['b'].copy()
100 loops, best of 3: 13.3 ms per loop