用相关列的平均值替换数据框中的 NaN 值的函数
Posted
技术标签:
【中文标题】用相关列的平均值替换数据框中的 NaN 值的函数【英文标题】:Function to replace NaN values in a dataframe with mean of the related column 【发布时间】:2018-12-14 21:23:32 【问题描述】:编辑:这个问题不是pandas dataframe replace nan values with average of columns 的克隆,因为我想用列的平均值而不是数据帧值的平均值替换每列的值。 p>
问题
我有一个包含一百列的 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()
方法的问题。
【问题讨论】:
pandas DataFrame: replace nan values with average of columns的可能重复 感谢您发布反馈。在我看来,这不是重复的:该问题用数据框的平均值替换值。我想替换特定列的平均值的每一列值。 我认为你可以使用 fillna() 方法:pandas.pydata.org/pandas-docs/version/0.17.0/generated/… 我现在正在编写代码示例。 哎呀@zipa 更快:) 有效!太好了,谢谢你们! 【参考方案1】:用各自的平均使用量填充每列的NaN
:
df.apply(lambda x: x.fillna(x.mean()))
【讨论】:
【参考方案2】:你可以试试这样的:
[df[col].fillna(df[col].mean(), inplace=True) for col in df.columns]
但这只是一种方法。 您的代码是先验的几乎是正确的。你的错误是你应该打电话
train[value]
而不是:
train['value']
代码中的任何地方。因为后者会尝试从您正在迭代的列表中查找名为“value”的列。
【讨论】:
【参考方案3】:你也可以使用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 的解决方案快两倍。
【讨论】:
以上是关于用相关列的平均值替换数据框中的 NaN 值的函数的主要内容,如果未能解决你的问题,请参考以下文章