Skip to main content
 首页 » 编程设计

python之用相关列的平均值替换数据框中的 NaN 值的函数

2025年05月04日13hnrainll

编辑: 这个问题不是 pandas dataframe replace nan values with average of columns 的克隆因为我想用列的平均值而不是数据帧值的平均值替换每列的值。

问题

我有一个包含一百列的 Pandas 数据框 (train),我必须对其应用机器学习技术。

通常我手工进行特征工程,但在这种情况下我有很多列要处理。

我想构建一个 Python 函数:

1) 在每一列中找到 NaN 值(我想过 df.isnull().any() )

2) 对于每个 NaN 值,将其替换为已找到 NaN 值的列的平均值。

我的想法是这样的:

def replace(value): 
    for value in train: 
        if train['value'].isnull(): 
           train['value'] = train['value'].fillna(train['value'].mean()) 
 
train = train.apply(replace,axis=1) 

但是我收到以下错误

--------------------------------------------------------------------------- 
KeyError                                  Traceback (most recent call last) 
/opt/conda/lib/python3.6/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance) 
   3063             try: 
-> 3064                 return self._engine.get_loc(key) 
   3065             except KeyError: 
 
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc() 
 
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc() 
 
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item() 
 
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item() 
 
KeyError: 'value' 
 
During handling of the above exception, another exception occurred: 
 
KeyError                                  Traceback (most recent call last) 
<ipython-input-25-003b3eb2463c> in <module>() 
----> 1 train = train.apply(replace,axis=1) 
 
/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py in apply(self, func, axis, broadcast, raw, reduce, result_type, args, **kwds) 
   6012                          args=args, 
   6013                          kwds=kwds) 
-> 6014         return op.get_result() 
   6015  
   6016     def applymap(self, func): 
 
/opt/conda/lib/python3.6/site-packages/pandas/core/apply.py in get_result(self) 
    140             return self.apply_raw() 
    141  
--> 142         return self.apply_standard() 
    143  
    144     def apply_empty_result(self): 
 
/opt/conda/lib/python3.6/site-packages/pandas/core/apply.py in apply_standard(self) 
    246  
    247         # compute the result using the series generator 
--> 248         self.apply_series_generator() 
    249  
    250         # wrap results 
 
/opt/conda/lib/python3.6/site-packages/pandas/core/apply.py in apply_series_generator(self) 
    275             try: 
    276                 for i, v in enumerate(series_gen): 
--> 277                     results[i] = self.f(v) 
    278                     keys.append(v.name) 
    279             except Exception as e: 
 
<ipython-input-22-2e7fa654e765> in replace(value) 
      1 def replace(value): 
      2     for value in train: 
----> 3         if train['value'].isnull(): 
      4            train['value'] = train['value'].fillna(df['value'].mean()) 
 
/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py in __getitem__(self, key) 
   2686             return self._getitem_multilevel(key) 
   2687         else: 
-> 2688             return self._getitem_column(key) 
   2689  
   2690     def _getitem_column(self, key): 
 
/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py in _getitem_column(self, key) 
   2693         # get column 
   2694         if self.columns.is_unique: 
-> 2695             return self._get_item_cache(key) 
   2696  
   2697         # duplicate columns & possible reduce dimensionality 
 
/opt/conda/lib/python3.6/site-packages/pandas/core/generic.py in _get_item_cache(self, item) 
   2484         res = cache.get(item) 
   2485         if res is None: 
-> 2486             values = self._data.get(item) 
   2487             res = self._box_item_values(item, values) 
   2488             cache[item] = res 
 
/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py in get(self, item, fastpath) 
   4113  
   4114             if not isna(item): 
-> 4115                 loc = self.items.get_loc(item) 
   4116             else: 
   4117                 indexer = np.arange(len(self.items))[isna(self.items)] 
 
/opt/conda/lib/python3.6/site-packages/pandas/core/indexes/base.py in get_loc(self, key, method, tolerance) 
   3064                 return self._engine.get_loc(key) 
   3065             except KeyError: 
-> 3066                 return self._engine.get_loc(self._maybe_cast_indexer(key)) 
   3067  
   3068         indexer = self.get_indexer([key], method=method, tolerance=tolerance) 
 
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc() 
 
pandas/_libs/index.pyx in pandas._libs.index.IndexEngine.get_loc() 
 
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item() 
 
pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.get_item() 
 
KeyError: ('value', 'occurred at index 0') 

在寻找解决方案时,我发现:

  • This但它适用于 txt 文件(不是 Pandas 数据框)

  • This关于 df.isnull().any() 方法的问题。

请您参考如下方法:

你也可以使用fillna

df = pd.DataFrame({'A': [1, 2, np.nan], 'B': [2, np.nan, np.nan]}) 
df.fillna(df.mean(axis=0)) 
    A   B 
0   1.0 2.0 
1   2.0 2.0 
2   1.5 2.0 

df.mean(axis=0) 计算每一列的平均值,并将其传递给 fillna 方法。

这个解决方案是在我的机器上,比上面显示的数据集使用 apply 的解决方案快两倍。