我有一个DataFrame
import pandas as pd
import numpy as np
df = pd.DataFrame( { 'val1': [1,np.nan,3], 'val2': [np.nan,5,6], 'val3': [7,np.nan,8], 'default': [ 42,43,44 ] } )
。
default val1 val2 val3
0 42 1 NaN 7
1 43 NaN 5 NaN
2 44 3 6 8
[3 rows x 3 columns]
我希望每个NaN都被列'default'中各自行中给出的默认值所取代。
我可以使用datafframe。fillna
在for循环中按列排列for col in [ 'val1', 'val2' ]:
df[ col ] = df[ col ].fillna( df['default'] )
,产生期望的结果
default val1 val2 val3
0 42 1 42 7
1 43 43 5 43
2 44 3 6 8
我想知道是否有一个非for循环,大概是一个更有效的解决方案?我的DataFrame可以包含几百列和几万行。
请确保使用双括号表示df[['default']]
是DataFrame而不是Series,否则您的结果将与预期输出不匹配。
>>> df.fillna(df[['default']].values)
default val1 val2 val3
0 42 1 42 7
1 43 43 5 43
2 44 3 6 8
在pandas 16.1+中,您需要为每个列传递一个Series,该Series可以使用字典推导式构建。
defaults = df['default']
>>> df.fillna({col: defaults for col in df})
default val1 val2 val3
0 42 1 42 7
1 43 43 5 43
2 44 3 6 8
由于在pandas 0.16.1版本中,我不能传递numpy。narray to DataFrame.fillna()(参见我对Alexander的回答的评论)
我可以传递一个DataFrame给df.fillna()。文档中说,这个DataFrame指定每个列的值。因此,我需要转置df,填充na,然后转置
df.T.fillna(df['default']).T
所以,它更短。但它也是最有效的吗?