使用 pandas 工具箱对非缺失列的平均值进行条件插补
Conditional imputation with average of non-missing columns with pandas toolbox
本题侧重于pandas自己的函数。仍然有解决方案(pandas DataFrame: replace nan values with average of columns)但是有自己的书面功能。
在 SPSS 中有一个函数 MEAN.n
可以给你数字列表的平均值 只有 当该列表的 n
元素有效时(not pandas.NA
).使用该功能,只有在最少数量的项目有效时,您才能估算缺失值。
是否有 pandas 函数来执行此操作?
例子
值[1, 2, 3, 4, NA]
。
有效值的平均值为 2.5
。
结果列表应该是 [1, 2, 3, 4, 2.5]
.
假设规则在 5 项列表中 3 应该具有有效的插补值。否则结果为 NA。
值[1, 2, NA, NA, NA]
。
有效值的平均值是 1.5
但这并不重要。
结果列表不应更改 [1, 2, NA, NA, NA]
,因为不允许插补。
让我们尝试列表理解,尽管它会很混乱
选项 1
你可以使用pd.Series和numpy
s= [x if np.isnan(lst).sum()>=3 else pd.Series(lst).mean(skipna=True) if x is np.nan else x for x in lst]
选项2一直使用numpy
s=[x if np.isnan(lst).sum()>=3 else np.mean([x for x in lst if str(x) != 'nan']) if x is np.nan else x for x in lst]
案例1
lst=[1, 2, 3, 4, np.nan]
结果
[1, 2, 3, 4, 2.5]
案例2
lst=[1, 2, np.nan, np.nan, np.nan]
结果
[1, 2, nan, nan, nan]
如果你想要它作为一个 pd。系列,简直
pd.Series(s, name='lst')
工作原理
s=[x if np.isnan(lst).sum()>=3 \ #give me element x if the sum of nans in the list is greater than or equal to 3
else pd.Series(lst).mean(skipna=True) if x is np.nan else x \# Otherwise replace the Nan in list with the mean of non NaN elements in the list
for x in lst\#For every element in lst
]
假设你想使用 pandas
,你可以定义一个自定义包装器(仅使用 pandas 函数)到 fillna
和 mean
只有至少项目数量不适用:
from pandas import NA
s1 = pd.Series([1, 2, 3, 4, NA])
s2 = pd.Series([1, 2, NA, NA, NA])
def fillna_mean(s, N=4):
return s if s.notna().sum() < N else s.fillna(s.mean())
fillna_mean(s1)
# 0 1.0
# 1 2.0
# 2 3.0
# 3 4.0
# 4 2.5
# dtype: float64
fillna_mean(s2)
# 0 1
# 1 2
# 2 <NA>
# 3 <NA>
# 4 <NA>
# dtype: object
fillna_mean(s2, N=2)
# 0 1.0
# 1 2.0
# 2 1.5
# 3 1.5
# 4 1.5
# dtype: float64
本题侧重于pandas自己的函数。仍然有解决方案(pandas DataFrame: replace nan values with average of columns)但是有自己的书面功能。
在 SPSS 中有一个函数 MEAN.n
可以给你数字列表的平均值 只有 当该列表的 n
元素有效时(not pandas.NA
).使用该功能,只有在最少数量的项目有效时,您才能估算缺失值。
是否有 pandas 函数来执行此操作?
例子
值[1, 2, 3, 4, NA]
。
有效值的平均值为 2.5
。
结果列表应该是 [1, 2, 3, 4, 2.5]
.
假设规则在 5 项列表中 3 应该具有有效的插补值。否则结果为 NA。
值[1, 2, NA, NA, NA]
。
有效值的平均值是 1.5
但这并不重要。
结果列表不应更改 [1, 2, NA, NA, NA]
,因为不允许插补。
让我们尝试列表理解,尽管它会很混乱
选项 1
你可以使用pd.Series和numpy
s= [x if np.isnan(lst).sum()>=3 else pd.Series(lst).mean(skipna=True) if x is np.nan else x for x in lst]
选项2一直使用numpy
s=[x if np.isnan(lst).sum()>=3 else np.mean([x for x in lst if str(x) != 'nan']) if x is np.nan else x for x in lst]
案例1
lst=[1, 2, 3, 4, np.nan]
结果
[1, 2, 3, 4, 2.5]
案例2
lst=[1, 2, np.nan, np.nan, np.nan]
结果
[1, 2, nan, nan, nan]
如果你想要它作为一个 pd。系列,简直
pd.Series(s, name='lst')
工作原理
s=[x if np.isnan(lst).sum()>=3 \ #give me element x if the sum of nans in the list is greater than or equal to 3
else pd.Series(lst).mean(skipna=True) if x is np.nan else x \# Otherwise replace the Nan in list with the mean of non NaN elements in the list
for x in lst\#For every element in lst
]
假设你想使用 pandas
,你可以定义一个自定义包装器(仅使用 pandas 函数)到 fillna
和 mean
只有至少项目数量不适用:
from pandas import NA
s1 = pd.Series([1, 2, 3, 4, NA])
s2 = pd.Series([1, 2, NA, NA, NA])
def fillna_mean(s, N=4):
return s if s.notna().sum() < N else s.fillna(s.mean())
fillna_mean(s1)
# 0 1.0
# 1 2.0
# 2 3.0
# 3 4.0
# 4 2.5
# dtype: float64
fillna_mean(s2)
# 0 1
# 1 2
# 2 <NA>
# 3 <NA>
# 4 <NA>
# dtype: object
fillna_mean(s2, N=2)
# 0 1.0
# 1 2.0
# 2 1.5
# 3 1.5
# 4 1.5
# dtype: float64