2017-01-04 76 views
0

我有兩個數據框,我希望更新列中的一個基於另一個。問題是,當我更新列時,舊數據框也會被重寫。熊貓在新的數據幀seting列替換舊的數據幀

(一個數據幀包含列和目標變量之間的相關性,另外是爲了顯示排名)

import numpy as np 
import pandas as pd 
from scipy.stats import pearsonr 
from sklearn.datasets import load_iris 

iris = load_iris() 
X = iris.data[:100] 
y = iris.target[:100] 
clmns = iris.feature_names 

out = pd.DataFrame(index=np.arange(0,len(clmns)), columns=['coef']) 

feat_coef = pd.DataFrame(columns=['Feature_name','pearson_koef_FM']) 

feat_coef['Feature_name'] = clmns 
feat_rank = feat_coef 

X_np = np.array(X) 
y_np = np.array(y) 
for idx,name in enumerate(clmns): 
    out['coef'].loc[idx] = pearsonr(X_np[:,idx], y_np)[0] 

feat_coef['pearson_koef_FM'] = np.absolute(out['coef']) 

print '----BEFORE----'  
print feat_coef 

feat_rank['pearson_koef_FM'] = feat_coef['pearson_koef_FM'].rank(ascending=False) 

print '----AFTER----'  
print feat_coef 

它返回這樣的:顯然

----BEFORE---- 
     Feature_name pearson_koef_FM 
0 sepal length (cm)   0.72829 
1 sepal width (cm)  0.684019 
2 petal length (cm)  0.969955 
3 petal width (cm)  0.960158 
----AFTER---- 
     Feature_name pearson_koef_FM 
0 sepal length (cm)    3.0 
1 sepal width (cm)    4.0 
2 petal length (cm)    1.0 
3 petal width (cm)    2.0 

,我預計feat_coef保持不變。如果我打印feat_rank,我會得到正確的輸出。我覺得在複製數據框時設置複製與視圖有關。

+1

'feat_rank'是__reference__,所以用'feat_rank = feat_coef.copy()' – MaxU

+0

我知道這會是這樣的替換'feat_rank = feat_coef'。完美的作品!你能解釋一下爲什麼請問? – HonzaB

回答

1

這一行後:

feat_rank = feat_coef 

feat_rankfeat_coef參考:

In [9]: feat_rank is feat_coef 
Out[9]: True 

In [10]: id(feat_rank) 
Out[10]: 177476664 

In [11]: id(feat_coef) 
Out[11]: 177476664 

In [12]: id(feat_coef) == id(feat_rank) 
Out[12]: True 

In [13]: feat_rank['new'] = 100 

In [14]: feat_coef 
Out[14]: 
     Feature_name pearson_koef_FM new 
0 sepal length (cm)   0.72829 100 
1 sepal width (cm)  0.684019 100 
2 petal length (cm)  0.969955 100 
3 petal width (cm)  0.960158 100 

因此,如果您更改參考DF feat_rank任何現有的列(值) - 這將是上完成來源DF feat_coef

解決方案: if你需要一個獨立的DF使用.copy()

feat_rank = feat_coef.copy()