基于默认值列在多个列中替换nan的最有效方法是什么?



我有一个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

所以,它更短。但它也是最有效的吗?

最新更新