2016-09-30 26 views
0

私の質問は、参照渡し時のpandas DataFrameの不変性に関するものです。 fooがpandas DataFrameを参照渡し

def foo(df1, df2): 

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

    return() 

(すなわち "として定義されている場合、出力は、

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 

ある

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) 

:次のコードを考えてみましょう他のステートメントの前に「join」ステートメント)出力は単純です

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)