首页 > 解决方案 > 从 Pandas 中的数据框行中查找最常见的值

问题描述

在数据框中,我想创建另一列,它输出来自一行中不同列的最频繁值。

A    B    C   D
foo  bar  baz foo
egg  bacon egg egg
bacon egg foo  baz

“E”列必须从一行输出频繁值,例如

E
foo
egg

我怎样才能在 Python 中做到这一点?

标签: pythonpandasdataframe

解决方案


重现您的问题:

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

推荐阅读