python - 从 Pandas 中的数据框行中查找最常见的值
问题描述
在数据框中,我想创建另一列,它输出来自一行中不同列的最频繁值。
A B C D
foo bar baz foo
egg bacon egg egg
bacon egg foo baz
“E”列必须从一行输出频繁值,例如
E
foo
egg
我怎样才能在 Python 中做到这一点?
解决方案
重现您的问题:
df = pd.DataFrame(
{
'A' : ['foo', 'egg', 'bacon'],
'B' : ['bar', 'bacon', 'egg'],
'C' : ['baz', 'egg', 'foo'],
'D' : ['foo', 'egg', 'baz']
}
)
并解决问题
df['E'] = df.mode(axis=1)[0]
输出:
A B C D E
0 foo bar baz foo foo
1 egg bacon egg egg egg
2 bacon egg foo baz bacon
如果没有一个最频繁的元素会发生什么?
df.mode(axis=1)
0 1 2 3
0 foo NaN NaN NaN
1 egg NaN NaN NaN
2 bacon baz egg foo
正如您所看到的,当出现最频繁时,它会返回最频繁集中的值。如果我分别在 C 和 D 列中将值 foo 换成 egg 和 baz 换成 bacon,我们得到以下结果:
0 1
0 foo NaN
1 egg NaN
2 bacon egg
如您所见,现在结果集只有两个元素,这意味着平局在培根和鸡蛋之间。
如何检测关系?
让我们使用不包含 D 列的数据集。
df
A B C
0 foo bar baz
1 egg bacon egg
2 bacon egg foo
df_m = df.mode(axis=1)
df_m
0 1 2
0 bar baz foo
1 egg NaN NaN
2 bacon egg foo
df['D'] = df_m[0]
A B C D
0 foo bar baz bar
1 egg bacon egg egg
2 bacon egg foo bacon
我们可以利用 pandas 提供的notna()方法来创建掩码来检查哪些行不包含 NaN 值,即哪些行处于平局。
首先,我们必须删除始终具有值的第一列。
df_m = df_m.drop(columns=0)
然后我们需要使用另一种方法.T转换数据帧,并检查任何不包含 NaN 的行。
df_mask = df_m.T.notna().any()
df_mask
0 False
1 False
2 True
dtype: bool
现在我们有一个熊猫系列的布尔值。我们可以使用这个掩码覆盖之前的列。
df['D'][df_mask] = df['A'][df_mask]
A B C D
0 foo bar baz foo
1 egg bacon egg egg
2 bacon egg foo bacon