今天的问题很简单,可能与DataFrame和来自它的分组数据框架之间的交互有关。
问题是我有一个具有name
,gender
和foo
变量的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(在此示例中为四而不是三)。这应该很简单,那么,我想念的是什么?
答案 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
中的df2
与aux
中的两行匹配,所以会生成两行。
左连接保证left
中的每一行至少被表示一次;
如果没有匹配项,则填充NaN值。
恰好在以下情况下,左联接返回的行可能多于left
的长度
right
中超过一行的行与left
中一行的行匹配。
docs here中有此行为的示例。如果搜索how='left'
,将发现一个示例,其中left
有4行,而right
有4行,但是合并有5行。请注意,(key1, key2)
对(K1, K0)
对如何两次代表。
内部联接仅返回匹配产生的所有可能的行。它的 与左联接基本相同,除了具有空匹配项和NaN值的行 被丢弃。