[英]Replacing dataframe values with NaN based on condition while preserving shape of df
Python新手在這里。 我確定我在問一個瑣碎的問題,但是不幸的是,在做完google-foo之后,我還沒有找到解決方案。 這樣就可以了:如果我有一個像這樣的數據框:
raw_data = {'first_name': ['Jason', 'Molly', 'Tina', 'Jake', 'Amy'],
'last_name': ['Miller', 'Jacobson', 'Ali', 'Milner', 'Cooze'],
'age': [42, 52, 36, 24, 73],
'preTestScore': [-999, -999, -999, 2, 1],
'postTestScore': [2, 2, -999, 2, -999]}
df = pd.DataFrame(raw_data, columns = ['first_name', 'last_name', 'age', 'preTestScore', 'postTestScore'])
如何執行以下操作:如果preTestScore = -999,則用NaN替換preTestScore和postTestScore?
我可以使用df.replace(-999,np.nan)將NaN替換為單個列值,但這需要在兩列之間有條件地刪除。
非常感謝你
將loc
與boolen掩碼和設置為NaN
的列列表一起使用:
df.loc[df['preTestScore'] == -999, ['preTestScore','postTestScore']] = np.nan
print (df)
first_name last_name age preTestScore postTestScore
0 Jason Miller 42 NaN NaN
1 Molly Jacobson 52 NaN NaN
2 Tina Ali 36 NaN NaN
3 Jake Milner 24 2.0 2.0
4 Amy Cooze 73 1.0 -999.0
詳細說明 :
print (df['preTestScore'] == -999)
0 True
1 True
2 True
3 False
4 False
Name: preTestScore, dtype: bool
pandas.DataFrame.mask
排隊
cols = ['preTestScore', 'postTestScore']
df.assign(**df[cols].mask(df[cols[0]].eq(-999)))
first_name last_name age preTestScore postTestScore
0 Jason Miller 42 NaN NaN
1 Molly Jacobson 52 NaN NaN
2 Tina Ali 36 NaN NaN
3 Jake Milner 24 2.0 2.0
4 Amy Cooze 73 1.0 -999.0
我使用cols
來避免寫長列名稱。 cols[0]
是編寫'preTestScore'
當preTestScore
為-999
時, df[cols].mask(df[cols[0]].eq(-999))
將使兩列np.nan
preTestScore
。
我使用assign
生成具有新列的數據框,而不會覆蓋舊數據框。 如果要保留此新數據框,請將結果分配給一個名稱。 您甚至可以使用舊名稱df = df.assign(**df[cols].mask(df[cols[0]].eq(-999)))
assign
帶有關鍵字參數的參數,您可以通過打開帶有雙splat **kwargs
的字典的包來傳遞。 方便地,當在字典上下文中使用數據框時,它完全按照我們想要的方式以列名作為關鍵字並以列作為值來解包。
cols = ['preTestScore', 'postTestScore']
df[cols] = df[cols].mask(df[cols[0]].eq(-999))
df
first_name last_name age preTestScore postTestScore
0 Jason Miller 42 NaN NaN
1 Molly Jacobson 52 NaN NaN
2 Tina Ali 36 NaN NaN
3 Jake Milner 24 2.0 2.0
4 Amy Cooze 73 1.0 -999.0
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.