我的情景是,一個函數應該能夠修改pandas.DataFrame
中的值。但我不想將整個DataFrame暴露給函數,只是需要修改的部分。這種透明度的一個原因是,該功能將更具有通用性,能夠指定從外部修改DataFrame的哪一部分。成像我可以編寫一個函數mult(df_view, a)
,將視圖中的所有值乘以a
。請注意,我不希望創建新的DataFrame。價值變化應該是就地。Python Pandas:如何將DataFrames的「視圖」傳遞給函數?
這是我的嘗試:
df = pd.DataFrame([[1,1],[1,1]])
def mult(df_view, a):
df_view *= a
mult(df.loc[1,1], 2)
print(df)
這是(不需要)輸出:
0 1
0 1 1
1 1 1
預期輸出是:
0 1
0 1 1
1 1 2
注意到,如果我們做的分配直接(即沒有功能),它的工作原理:
df = pd.DataFrame([[1,1],[1,1]])
df.loc[1,1] *= 2
print(df)
...給:
0 1
0 1 1
1 1 2
因此,通過該視圖通過函數調用時,顯然我搞亂了的東西。我讀過這個blog post from Jeff Knupp,我想我明白python的名稱 - 對象綁定是如何工作的。我對DataFrames的理解是,當我呼叫df.loc[1,1]
時,它會生成一個代理對象,該對象指向原始DataFrame w/[1,1]
窗口,以便進一步的操作(例如分配)只轉到窗口內的元素。現在,當我通過函數調用傳遞df.loc[1,1]
時,該函數將名稱df_view
綁定到代理對象。因此,在我的理論中,任何變化(即df_view *= a
)都應該應用於視圖,並因此應用於原始DataFrame中的元素。從結果中,很明顯這沒有發生,看起來DataFrame在進程中被複制(我不確定在哪裏),因爲一些值在原始DataFrame之外被更改了。
是'numpy.int64'並不意味着在數據幀中值的數據不能被分配至。實際上它在'df.loc [1,1] * = 2'的情況下。正如你所指出的那樣,何時/爲什麼傳遞一個「視圖」到'mult()'函數的邏輯會有點不清楚。這不是一個明確的答案(儘管你指出了一些成功的和失敗的案例有幫助)。 – Roy
@Roy Python通過賦值傳遞,當你直接使用'df.loc [1,1] * = 2'時,你仍然分配給DataFrame的_element_,而不是傳遞給函數的實際值。 [這是一個很好的閱讀](http://nedbatchelder.com/text/names.html)。 – miradulo