[英]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.