与groupby一起使用自定义聚合时的KeyError

时间:2018-03-11 01:23:07

标签: python pandas pandas-groupby

我正在尝试使用pandas执行多个聚合(某些自定义),但是当我使用KeyError: 'type'时,我得到agg。我以为我正在编写自己的聚合,但显然不是。如何更改自己的聚合count_tweets()count_retweets(),以便在新数据框中正确提供推文和转推的计数。

# create example data
df = pd.DataFrame([['user1', 'tweet', 400],
                   ['user1', 'retweet', 405],
                   ['user2', 'tweet', 10],
                   ['user2', 'tweet', 10],
                   ['user1', 'tweet', 450],
                   ['user3', 'retweet', 8],
                   ['user1', 'tweet', 500]],
                  columns=['user', 'type', 'followers'])

# group by user
grouped = df.groupby('user')

# create custom aggregration to count tweets
def count_tweets(arr):
    return len(arr[arr['type'] == 'tweet'])

# create custom aggregration to count retweets
def count_retweets(arr):
    return len(arr[arr['type'] == 'retweet'])

# define aggregrations
args = {'followers': 'mean',
        'type': 'count',
        'type': [count_tweets, count_retweets]}

# apply aggregrations to grouped data
results = grouped.agg(args)

KeyError: 'type'

1 个答案:

答案 0 :(得分:2)

使用agg时,它将在系列对象上使用这些函数。因此,当您指定count_tweets应该在列type上运行时,没有理由尝试在函数内再次获取类型列。

def count_tweets(arr):
    return len(arr[arr == 'tweet'])

def count_retweets(arr):
    return len(arr[arr == 'retweet'])

# define aggregrations
args = {
    'followers': 'mean',
    'type': ['count', count_tweets, count_retweets]
}

df.groupby('user').agg(args)

      followers  type                            
           mean count count_tweets count_retweets
user                                             
user1    438.75     4            3              1
user2     10.00     2            2              0
user3      8.00     1            0              1

那就是说,我不喜欢你是怎么做到的。无论如何,请使用我对代码的更正。但是,如果您有兴趣,我更喜欢这些方法。

选项1
您可以使用groupby pipe方法对此进行管道处理。我将agg组合起来处理meancount并使用value_counts来处理计数类型的类型。

df.groupby('user').pipe(
    lambda g: g.agg(dict(followers='mean', type='count'))
               .join(g.type.value_counts().unstack(fill_value=0))
)

       followers  type  retweet  tweet
user                                  
user1     438.75     4        1      3
user2      10.00     2        0      2
user3       8.00     1        1      0

选项2
pd.get_dummies

之前使用groupby
df.join(pd.get_dummies(df.type)).groupby('user').agg(
    dict(followers='mean', type='count', retweet='sum', tweet='sum')
)

       followers  type  retweet  tweet
user                                  
user1     438.75     4        1      3
user2      10.00     2        0      2
user3       8.00     1        1      0