2016-09-30 160 views
0

我的問題是關於熊貓DataFrame在通過引用傳遞時的不可變性。考慮下面的代碼:通過引用傳遞熊貓DataFrame

import pandas as pd 

def foo(df1, df2): 

    df1['B'] = 1 
    df1 = df1.join(df2['C'], how='inner') 

    return() 

def main(argv = None): 

    # Create DataFrames. 
    df1 = pd.DataFrame(range(0,10,2), columns=['A']) 
    df2 = pd.DataFrame(range(1,11,2), columns=['C']) 

    foo(df1, df2) # Pass df1 and df2 by reference. 

    print df1 

    return(0) 

if __name__ == '__main__': 
    status = main() 
    sys.exit(status) 

輸出是

A B 
0 0 1 
1 2 1 
2 4 1 
3 6 1 
4 8 1 

和不

A B C 
0 0 1 1 
1 2 1 3 
2 4 1 5 
3 6 1 7 
4 8 1 9 

事實上,如果FOO被定義爲

def foo(df1, df2): 

    df1 = df1.join(df2['C'], how='inner') 
    df1['B'] = 1 

    return() 

(即「加入「聲明之前的其他陳述)然後輸出僅僅是

A  
0 0 
1 2 
2 4 
3 6 
4 8 

我好奇,爲什麼是這種情況。任何見解,將不勝感激。

+0

順便說一句,回報是不是一個函數,它只是一個說法,這樣你就不會後所需要的支架。 – Jezzamon

+0

[This](http://nedbatchelder.com/text/names.html)是我知道Python名稱工作方式的最佳討論。一旦你明白了,你就會理解這種行爲。 – chthonicdaemon

+0

謝謝@chthonicdaemon! – labrynth

回答

2

的問題是因爲該行的:

df1 = df1.join(df2['C'], how='inner') 

df1.join(df2['C'], how='inner')返回一個新的數據幀。在此行之後,df1不再引用與參數相同的數據幀,而是新引用,因爲它已被重新分配給新結果。第一個數據框繼續存在,未經修改。這不是一個真正的熊貓問題,只是python和大多數其他語言的一般方式。

一些熊貓函數有一個inplace參數,它可以做你想做的事,但是連接操作不會。如果你需要修改一個數據框,你將不得不返回這個新的數據,並將它重新分配給函數外部。

+0

謝謝@Jezzamon。這說得通。 – labrynth

3

Python沒有通過值與傳遞參考 - 只有bindings from names to objects

如果你改變你的函數

def foo(df1, df2): 

    res = df1.join(df2['C'], how='inner') 
    res['B'] = 1 

    return res 

然後df1df2,在功能上,也必然給你發送的對象。 join(在這種情況下是新對象)的結果綁定到名稱res。您可以操縱它並將其返回,而不會影響其他任何對象或綁定。

在調用代碼,你可以只寫

print foo(df1, df2)