groupby数据框和原始数据框之间的左合并带来了外部合并

时间:2018-12-02 01:40:34

标签: python pandas dataframe

今天的问题很简单,可能与DataFrame和来自它的分组数据框架之间的交互有关。

问题是我有一个具有namegenderfoo变量的DataFrame,如下所示:

name    gender   foo
John      M       a
James     M       b
Jenny     F       c
John      M       d

我想要做的是获取一个具有每个名称的出现次数及其性别的DataFrame。我尝试过:

df2=df.groupby('name', as_index=False).count()[['name','foo']]
aux=df[['name','gender']]
df2=df2.merge(aux, on='name', how='left')

但是,这带来了一个与原始DataFrame具有相同行数的DataFrame(在此示例中为四而不是三)。这应该很简单,那么,我想念的是什么?

2 个答案:

答案 0 :(得分:2)

因此,让我们使用agg

df.groupby('name',as_index=False).agg({'gender':'first','foo':'count'})
    name gender  foo
0  James      M    1
1  Jenny      F    1
2   John      M    2

答案 1 :(得分:1)

将重复项放在aux中:

aux = df[['name', 'gender']].drop_duplicates()

import pandas as pd

df = pd.DataFrame({'foo': ['a', 'b', 'c', 'd'],
                   'gender': ['M', 'M', 'F', 'M'],
                   'name': ['John', 'James', 'Jenny', 'John']})
df2 = df.groupby('name', as_index=False)['foo'].count()
aux = df[['name', 'gender']].drop_duplicates()
df2 = df2.merge(aux, on='name', how='left')
print(df2)

收益

    name  foo gender
0  James    1      M
1  Jenny    1      F
2   John    2      M

顺便说一句,您可以使用

df2 = df.groupby('name', as_index=False)['foo'].count()

代替

df2 = df.groupby('name', as_index=False).count()[['name','foo']]

这有点效率,因为它避免了对gender列的计数。


pd.merge(left, right, how='left')left中的每一行创建一行,与right中的一行匹配。

pd.merge(df2, aux, on='name', how='left')中, 由于John中的df2aux中的两行匹配,所以会生成两行。

左连接保证left中的每一行至少被表示一次; 如果没有匹配项,则填充NaN值。 恰好在以下情况下,左联接返回的行可能多于left的长度 right中超过一行的行与left中一行的行匹配。

docs here中有此行为的示例。如果搜索how='left',将发现一个示例,其中left有4行,而right有4行,但是合并有5行。请注意,(key1, key2)(K1, K0)对如何两次代表。

内部联接仅返回匹配产生的所有可能的行。它的 与左联接基本相同,除了具有空匹配项和NaN值的行 被丢弃。