2017-02-24 30 views
2

我有一个DataFrame,我想用包含上一行数据的列进行扩展。在指定熊猫分栏时处理SettingWithCopyWarning问题

这个脚本做这项工作:

#!/usr/bin/env python3 

import numpy as np 
import pandas as pd 

n = 2 

df = pd.DataFrame({'A': [1,2,3,4,5], 'B': [0,1,1,0,0]}, columns=['A', 'B']) 

df2 = df[df['B'] == 0] 
print(df2) 

for i in range(1, n+1): 
    df2['A_%d' % i] = df2['A'].shift(i) 

print(df2) 

它输出:

A B 
0 1 0 
3 4 0 
4 5 0 

    A B A_1 A_2 
0 1 0 NaN NaN 
3 4 0 1.0 NaN 
4 5 0 4.0 1.0 

这正是我想要的。 DataFrame现在有两个额外的列A_1A_2,它们包含行之前的列的值A 和行。

不过,我也得到警告:

./my_script.py:14: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame. 
Try using .loc[row_indexer,col_indexer] = value instead 

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy 
    df2['A_%d' % i] = df2['A'].shift(i) 

问题肯定来自于过滤,我创建df2之前。如果我直接在df上工作,则不会发生此问题。 在我的应用程序中,我需要独立处理原始DataFrame的多个部分,因此需要过滤,并且绝对是必需的。所有不同的部分(如此处的df2)将在稍后进行连接。

我在How to deal with SettingWithCopyWarning in Pandas?Pandas SettingWithCopyWarning中发现了类似的问题,但是那里的解决方案没有解决问题。

写入例如

df2[:, 'A_%d' % i] = df2['A'].shift(i) 

仍然发生同样的警告。

我使用Python 3.5.2和大熊猫工作0.19.2

回答

3

我想你需要copy

df2 = df[df['B'] == 0].copy() 

如果您在df2修改值以后你会发现,这些修改不传播回到原始数据(df),熊猫会做出警告。

+1

它的工作原理。你能解释为什么在这种情况下需要调用'copy()'吗?特别是因为代码似乎没有它(除了警告)没有问题。 –

+0

解释对我来说很难。也许更好的解释[这](http://stackoverflow.com/a/38810015/2901002) – jezrael

+0

好的,谢谢,我想我现在明白了。 –