使用 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 函数)到 fillnamean 只有至少项目数量不适用:

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