我有这个数据帧
df = pd.DataFrame({"A": [10, 10, 10, 22, 30, 30, 30, 30, 30], "B": ["a", "a", "b", "b", "b", "a", "b", "b", "b"], "C": [2, 5, 10, np.nan, 15, 20, 35, 35, 35]})
所以我的数据帧看起来像这样
Index A B C
0 10 a 2
1 10 a 5
2 10 b 10
3 22 b nan
4 30 b 15
5 30 a 20
6 30 b 35
7 30 b 35
8 30 b 35
在第 3 行,我想根据满足这些条件的 C 列中的值插补 C 列。
- A 中最接近的值(包括其自身(。 对于第 3 行,A 中 22 的最接近值是 30。 (如果其他行中有 22,则最接近的值为 22(
- B 中的值相同。 对于第 3 行,B 的值为 b。
- C 中的多数值。 对于第 3 行,我们可以看到第 4、5、6、7、8 行满足前 2 个条件,但 C 中的多数值为 35。
因此,C 列第 3 行的预期输出为 35。 我可以用蛮力方法编写代码,但我想知道我们是否可以做更优雅的方式。
定义以下函数:
def findVal(row):
iMin = (df1[df1.B == row.B].A - row.A).abs().idxmin()
aClo = df1.loc[iMin].A
return df1[df1.A.eq(aClo) & df1.B.eq(row.B)].C.mode().iloc[0]
描述:
- row(参数( - 要为其找到C值的行。
- df1- 此处查找数据。
- iMin- 与A最接近的行位于此索引处。
- aClo-A的最接近值。
- 返回的值:
- 查找具有最接近的A和相同B的行。
- 从中返回最常出现的C值。
然后从df生成df1- 具有非空值C的行。
df1 = df[df.C.notna()]
要填充缺失值,请运行:
df.C.update(df[df.C.isna()].apply(findVal, axis=1))
描述:
- DF[DF.C.isna((]- 查找具有空值C的行。
- .apply(...(- 将findVal应用于每个这样的行。
- 结果是一个系列,其中包含:
- 具有缺失值的行的索引,
- 由 findVal返回的值。
- DF.C.更新(...(- 上述系列在指示的索引处更新C列。