Pandas 对多列进行行过滤
Pandas row filtering on multiple columns
我正在尝试过滤以下 pandas 数据框。
id X_1 X_2 X_4 M_1 M_2 M_3
0 i24 Nan 0.27 Nan 0.20 0.25 0.27
1 i25 0.45 0.47 0.46 0.42 Nan 0.42
2 i11 Nan Nan 0.32 0.32 0.35 0.29
3 i47 Nan 0.56 0.59 Nan 0.56 0.51
特别是,我想分别处理 M_ 列和 X_columns 并且只保留那些对于每个“组”M 和 X 至少有两个非 Nan 值的条目。
例如。不应包括条目 i24,因为它在 X_1 和 X_4 中的值都是 Nan,在 X“组”中只留下一个正确的值。 i25 和 i47 应该保留,因为它们尊重约束。
感谢任何能提供帮助的人。
ndf = df.set_index("id")
good_rows = (ndf.groupby(lambda col: col.split("_", maxsplit=1)[0], axis=1)
.count()
.ge(2)
.all(axis=1))
ndf = ndf.loc[good_rows]
这里我们先设置id
作为索引,放在一边。然后按列名称分组,直到第一个 _
,然后计算非 NaN 值。如果 X
和 M
计数都大于或等于 2,我们称它为好行。然后用这些行建立索引,
得到
>>> ndf
X_1 X_2 X_4 M_1 M_2 M_3
id
i25 0.45 0.47 0.46 0.42 NaN 0.42
i47 NaN 0.56 0.59 NaN 0.56 0.51
请注意,这假设这些值为 NaN
;如果不是字符串,请事先执行此操作:
df = df.replace("Nan", np.nan)
可以先把X
列和M
列的列表分开,然后用apply
检查两个列组是否满足小于2的条件NaN
值,然后相应地创建掩码,最后使用掩码得到所需的结果。
xCols = [col for col in df if col.startswith('X')] # ['X_1', 'X_2', 'X_4']
mCols = [col for col in df if col.startswith('M')] # ['M_1', 'M_2', 'M_3']
df[df.apply(lambda row: sum(row[mCols].isna())<2 and sum(row[xCols].isna())<2, axis=1)]
输出:
id X_1 X_2 X_4 M_1 M_2 M_3
1 i25 0.45 0.47 0.46 0.42 NaN 0.42
3 i47 NaN 0.56 0.59 NaN 0.56 0.51
我正在尝试过滤以下 pandas 数据框。
id X_1 X_2 X_4 M_1 M_2 M_3
0 i24 Nan 0.27 Nan 0.20 0.25 0.27
1 i25 0.45 0.47 0.46 0.42 Nan 0.42
2 i11 Nan Nan 0.32 0.32 0.35 0.29
3 i47 Nan 0.56 0.59 Nan 0.56 0.51
特别是,我想分别处理 M_ 列和 X_columns 并且只保留那些对于每个“组”M 和 X 至少有两个非 Nan 值的条目。 例如。不应包括条目 i24,因为它在 X_1 和 X_4 中的值都是 Nan,在 X“组”中只留下一个正确的值。 i25 和 i47 应该保留,因为它们尊重约束。
感谢任何能提供帮助的人。
ndf = df.set_index("id")
good_rows = (ndf.groupby(lambda col: col.split("_", maxsplit=1)[0], axis=1)
.count()
.ge(2)
.all(axis=1))
ndf = ndf.loc[good_rows]
这里我们先设置id
作为索引,放在一边。然后按列名称分组,直到第一个 _
,然后计算非 NaN 值。如果 X
和 M
计数都大于或等于 2,我们称它为好行。然后用这些行建立索引,
得到
>>> ndf
X_1 X_2 X_4 M_1 M_2 M_3
id
i25 0.45 0.47 0.46 0.42 NaN 0.42
i47 NaN 0.56 0.59 NaN 0.56 0.51
请注意,这假设这些值为 NaN
;如果不是字符串,请事先执行此操作:
df = df.replace("Nan", np.nan)
可以先把X
列和M
列的列表分开,然后用apply
检查两个列组是否满足小于2的条件NaN
值,然后相应地创建掩码,最后使用掩码得到所需的结果。
xCols = [col for col in df if col.startswith('X')] # ['X_1', 'X_2', 'X_4']
mCols = [col for col in df if col.startswith('M')] # ['M_1', 'M_2', 'M_3']
df[df.apply(lambda row: sum(row[mCols].isna())<2 and sum(row[xCols].isna())<2, axis=1)]
输出:
id X_1 X_2 X_4 M_1 M_2 M_3
1 i25 0.45 0.47 0.46 0.42 NaN 0.42
3 i47 NaN 0.56 0.59 NaN 0.56 0.51