pandas DataFrame:用列的平均值替换 nan 值
- 2025-01-13 08:52:00
- admin 原创
- 106
问题描述:
nan
我有一个 pandas DataFrame,其中主要填充了实数,但其中也有一些值。
我怎样才能nan
用所在列的平均值替换 s?
这个问题与这个问题非常相似:numpy array: replace nan values with average of columns, but, 不幸的是,那里给出的解决方案不适用于 pandas DataFrame。
解决方案 1:
您可以直接使用DataFrame.fillna
来填充nan
:
In [27]: df
Out[27]:
A B C
0 -0.166919 0.979728 -0.632955
1 -0.297953 -0.912674 -1.365463
2 -0.120211 -0.540679 -0.680481
3 NaN -2.027325 1.533582
4 NaN NaN 0.461821
5 -0.788073 NaN NaN
6 -0.916080 -0.612343 NaN
7 -0.887858 1.033826 NaN
8 1.948430 1.025011 -2.982224
9 0.019698 -0.795876 -0.046431
In [28]: df.mean()
Out[28]:
A -0.151121
B -0.231291
C -0.530307
dtype: float64
In [29]: df.fillna(df.mean())
Out[29]:
A B C
0 -0.166919 0.979728 -0.632955
1 -0.297953 -0.912674 -1.365463
2 -0.120211 -0.540679 -0.680481
3 -0.151121 -2.027325 1.533582
4 -0.151121 -0.231291 0.461821
5 -0.788073 -0.231291 -0.530307
6 -0.916080 -0.612343 -0.530307
7 -0.887858 1.033826 -0.530307
8 1.948430 1.025011 -2.982224
9 0.019698 -0.795876 -0.046431
的文档字符串fillna
表示value
应该是一个标量或一个字典,但是,它似乎也可以与一起使用Series
。如果您想传递一个字典,您可以使用df.mean().to_dict()
。
解决方案 2:
尝试:
sub2['income'].fillna((sub2['income'].mean()), inplace=True)
解决方案 3:
虽然下面的代码可以完成这项工作,但是它的性能会受到很大的影响,因为您要处理的 DataFrame 中有 100k 条或更多的记录:
df.fillna(df.mean())
根据我的经验,应该仅在需要的地方替换 NaN 值(无论是平均值还是中位数),而不是在整个 DataFrame 上应用 fillna() 。
我有一个包含 20 个变量的 DataFrame,其中只有 4 个需要 NaN 值处理(替换)。我尝试了上述代码(代码 1)以及略微修改后的版本(代码 2),其中我选择性地运行它。即仅对具有 NaN 值的变量运行
#------------------------------------------------
#----(Code 1) Treatment on overall DataFrame-----
df.fillna(df.mean())
#------------------------------------------------
#----(Code 2) Selective Treatment----------------
for i in df.columns[df.isnull().any(axis=0)]: #---Applying Only on variables with NaN values
df[i].fillna(df[i].mean(),inplace=True)
#---df.isnull().any(axis=0) gives True/False flag (Boolean value series),
#---which when applied on df.columns[], helps identify variables with NaN values
以下是我观察到的性能,因为我不断增加 DataFrame 中的记录数
包含约 100k 条记录的 DataFrame
代码 1:22.06 秒
代码 2:0.03 秒
包含约 200k 条记录的 DataFrame
代码 1:180.06 秒
代码 2:0.06 秒
包含约 160 万条记录的 DataFrame
代码 1:代码不断运行
代码 2:0.40 秒
包含约 1300 万条记录的 DataFrame
代码 1:——在看到 1.6 Mn 记录的表现后,甚至没有尝试——
代码 2:3.20 秒
抱歉回答太长了!希望这对你有帮助!
解决方案 4:
In [16]: df = DataFrame(np.random.randn(10,3))
In [17]: df.iloc[3:5,0] = np.nan
In [18]: df.iloc[4:6,1] = np.nan
In [19]: df.iloc[5:8,2] = np.nan
In [20]: df
Out[20]:
0 1 2
0 1.148272 0.227366 -2.368136
1 -0.820823 1.071471 -0.784713
2 0.157913 0.602857 0.665034
3 NaN -0.985188 -0.324136
4 NaN NaN 0.238512
5 0.769657 NaN NaN
6 0.141951 0.326064 NaN
7 -1.694475 -0.523440 NaN
8 0.352556 -0.551487 -1.639298
9 -2.067324 -0.492617 -1.675794
In [22]: df.mean()
Out[22]:
0 -0.251534
1 -0.040622
2 -0.841219
dtype: float64
对每列应用该列的平均值并填充
In [23]: df.apply(lambda x: x.fillna(x.mean()),axis=0)
Out[23]:
0 1 2
0 1.148272 0.227366 -2.368136
1 -0.820823 1.071471 -0.784713
2 0.157913 0.602857 0.665034
3 -0.251534 -0.985188 -0.324136
4 -0.251534 -0.040622 0.238512
5 0.769657 -0.040622 -0.841219
6 0.141951 0.326064 -0.841219
7 -1.694475 -0.523440 -0.841219
8 0.352556 -0.551487 -1.639298
9 -2.067324 -0.492617 -1.675794
解决方案 5:
如果您想要用平均值来填补缺失值,并且想要逐列进行填补,那么这将仅使用该列的平均值来填补。这可能更易读一些。
sub2['income'] = sub2['income'].fillna((sub2['income'].mean()))
解决方案 6:
# To read data from csv file
Dataset = pd.read_csv('Data.csv')
X = Dataset.iloc[:, :-1].values
# To calculate mean use imputer class
from sklearn.impute import SimpleImputer
imputer = SimpleImputer(missing_values=np.nan, strategy='mean')
imputer = imputer.fit(X[:, 1:3])
X[:, 1:3] = imputer.transform(X[:, 1:3])
解决方案 7:
直接用df.fillna(df.mean())
平均值填充所有空值
如果你想用该列的平均值填充空值,那么你可以使用它
假设x=df['Item_Weight']
这里Item_Weight
是列名
这里我们分配(用 x 的平均值填充 x 的空值到 x 中)
df['Item_Weight'] = df['Item_Weight'].fillna((df['Item_Weight'].mean()))
如果你想用一些字符串填充空值,那么使用
这Outlet_size
是列名
df.Outlet_Size = df.Outlet_Size.fillna('Missing')
解决方案 8:
Pandas:如何nan
用某一列的平均值、中位数或其他统计数据替换 NaN()值
假设你的 DataFrame 是df
,并且有一列名为nr_items
。这是: df['nr_items']
如果您想用列的平均值替换NaN
列的值:df['nr_items']
使用方法.fillna()
:
`mean_value=df['nr_items'].mean()
df['nr_item_ave']=df['nr_items'].fillna(mean_value)`
我创建了一个df
名为的新列,nr_item_ave
用于存储新列,其值由该列的值NaN
替换。mean
使用时应小心谨慎mean
。如果有异常值,则更建议使用median
解决方案 9:
除上述选项外,另一个选择是:
df = df.groupby(df.columns, axis = 1).transform(lambda x: x.fillna(x.mean()))
它不如以前对平均值的响应优雅,但如果您希望用其他列函数替换空值,它可能会更短。
解决方案 10:
使用 sklearn 库预处理类
from sklearn.impute import SimpleImputer
missingvalues = SimpleImputer(missing_values = np.nan, strategy = 'mean', axis = 0)
missingvalues = missingvalues.fit(x[:,1:3])
x[:,1:3] = missingvalues.transform(x[:,1:3])
注意:在最新版本中,参数missing_values
值更改np.nan
为NaN
解决方案 11:
我使用此方法通过一列的平均值填充缺失值。
fill_mean = lambda col : col.fillna(col.mean())
df = df.apply(fill_mean, axis = 0)
解决方案 12:
您还可以使用它value_counts
来获取最常见的值。这适用于不同的数据类型。
df = df.apply(lambda x:x.fillna(x.value_counts().index[0]))
这是 value_counts api 参考。