考慮以下單列數據框:
df = pd.DataFrame({'Actor': ['Sean Connery', 'Sean Connery',
'Sean Something', 'Sean Something Else']})
df
Out:
Actor
0 Sean Connery
1 Sean Connery
2 Sean Something
3 Sean Something Else
這是您要的面具用於切片:
現在
mask = df['Actor'] == 'Sean Connery'
,如果我用df[mask]['Actor'] = 'Sir Sean Connery'
,這將是執行:
df.__getitem__(mask).__setitem__('Actor', 'Sir Sean Connery')
__main__:1: 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
見警告文檔中:http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-versus-copy
而且對於這種情況也不會修改原來的DataFrame:
df
Out:
Actor
0 Sean Connery
1 Sean Connery
2 Sean Something
3 Sean Something Else
Id did雖然修改了一個DataFrame - 這是由__getitem__
方法返回的,但由於它沒有分配給任何東西,所以丟失了。
相反,在你的第二個例子(df[mask] = 'Sir Sean Connery'
)執行的代碼是:
df.__setitem__(mask, 'Sir Sean Connery')
由於面膜的你可能認爲它使用__getitem__
太多,但事實並非如此。它直接使用__setitem__
並將掩碼傳遞給該DataFrame。大熊貓可以確保我們可以確信它將在一個視圖上運行。對於__getitem__
的情況來說,它可以是複製或者它可以是一個視圖 - 很難知道。現在
你會看到,原來的DF修改:
df
Out:
Actor
0 Sir Sean Connery
1 Sir Sean Connery
2 Sean Something
3 Sean Something Else
這裏有一個陷阱,但。它的工作原因是我們只有一列。如果我們有另一欄,說'年',它會將相應的年份值設置爲'Sir Sean Connery'。爲了避免這一點,我們使用.loc
jezrael指出。它還調用__setitem__
方法並允許指定哪些列將會更改。
df = pd.DataFrame({'Actor': ['Sean Connery', 'Sean Connery',
'Sean Something', 'Sean Something Else'],
'Year': [1990, 1990, 1990, 1990]})
df.loc.__setitem__((mask, 'Actor'), 'Sir Sean Connery')
df
Out:
Actor Year
0 Sir Sean Connery 1990
1 Sir Sean Connery 1990
2 Sean Something 1990
3 Sean Something Else 1990
結果,最佳實踐是基於集合的口罩和欄姓名(或名稱)是使用.loc
:
df.loc[mask, 'Actor'] = 'Sir Sean Connery'
這樣你就不必如果您在操作擔心在副本上。
在第一個示例中,您鏈接了索引。 'bond [mask]'是DataFrame的一個拷貝,然後你用Actor列進一步索引它。在第二個'mask'只是一個布爾數組。你沒有修改蒙版。 – ayhan
'bond [mask] [「Actor」] =「Sean Connery爵士」和「bond [mask] =」Sean Connery爵士「之間的區別在於,在第一個中,您調用副本的__getitem__然後'__setitem__',但在第二個中只使用'__setitem__',這使得它在視圖上運行。 – ayhan
@ayhan:對不起,還不清楚。爲什麼這兩個案件都有不同的行爲。我期望他們都返回原始DataFrame(行或列)的引用。出於某種原因,顯然第一個返回一個副本,而不是原件。這是什麼原因?其次,根據我對這個鏈接http://pandas.pydata.org/pandas-docs/stable/indexing.html#returning-a-view-versus-a-copy的理解,在答案中共享,'__getitem__'將會在第一種情況下稱爲兩次,而在第二種情況下只調用一次。 –