在pandas中需要有效的groupby帮助

问题描述 投票:1回答:1

我有以下df,其中包含有关客户,事件日和花费的价值的信息:pandas dataframe

代码重现df:

d = {'CLIENT': ['John', 'Jonas', 'Mary', 'Anne', 'John', 'Jonas', 'Mary','John', 'Mary'],'SPENT': [30, 400, 800, 90, 180, 560, 50, 200, 100],'DAY_EVENT': ['WED', 'SAT', 'SUN', 'MON', 'FRI', 'WED', 'THU', 'FRI', 'SUN']}
df = pd.DataFrame(data=d)

我首先使用以下聚合选项制作了df.groupby

df_cli = df.groupby('CLIENT').agg({'SPENT': [np.size, np.sum, np.mean]}).reset_index()

这让我有这个:pandas groupby dataframe

我想为我的客户确定首选和最不喜欢的日子,但我不知道如何将它变成groupby函数的变量,所以我尝试了另一个groupby df:

df_cli_day = df.groupby(['CLIENT','DAY_EVENT']).agg({'SPENT':[np.size, np.sum, np.mean]}).reset_index(level=1)

然后我有这个:another pandas groupby dataframe

我已尝试执行此定义函数,然后将它们应用于数据框,如下所示:

def preferred_day(row): 
   cli = df_cli['CLIENT'][row]
   clidays = df_cli_day.loc[cli]
   return clidays['DAY_EVENT'].max()

def least_preferred_day(row):
    cli = df_cli['CLIENT'][row]
    clidays = df_cli_day.loc[cli]
    return clidays['DAY_EVENT'].min()

df_cli['preferred_day'] = df_cli.apply(lambda row:  preferred_day(row), axis=1)

这提出了以下内容:

 ValueError: ('cannot index with vector containing NA / NaN values', 'occurred at index 0')

由于我的函数在调用时起作用,我通过循环并将结果附加到列表,然后将它们转换为系列,最后将它们分配给df中的列来解决,如下面的代码所示:

preferred_list = []
least_preferred_list = []

for i in range(df_cli['CLIENT'].size): 
    preferred_list.append(preferred_day(i))
    least_preferred_list.append(least_preferred_day(i))

prefered_day_s = pd.Series(preferred_list)
least_preferred_day_s = pd.Series(least_preferred_list)
df_cli['preferred_day'] = preferred_day_s
df_cli['least_preferred_day'] = least_preferred_day_s

这让我得到了我想要的结果,但它很慢。

我需要一种方法来摆脱使用df.apply时的ValueError,或者另一种方法来更快地获得相同的结果。

python pandas pandas-groupby
1个回答
1
投票

首先,ValueError正在发生,因为row在传递给你的函数时是一个Series。这是apply的工作方式(见the docs)。您似乎期望row是一个数字索引,这是不正确的。永远不需要从传递给apply的函数中引用原始数据帧

你和你的第二个groupby在正确的轨道上,但更快的方法是分两个阶段,如下:

def most_frequent_day(group):
    ''' Return most frequent DAY_EVENT occurrence for group. '''
    return group['DAY_EVENT'].value_counts().apply(['max', 'idxmax'])

df.groupby('CLIENT').apply(most_frequent_day)

通过将applygroupby一起使用,函数most_frequent_day将为每个客户端调用一次,其中包含该客户端的原始数据框中的条目子集。对于每个子集,您可以简单地找到DAY_EVENT的最高频率。这将返回结果:

DAY_EVENT  max idxmax
CLIENT               
Anne         1    MON
John         2    FRI
Jonas        1    SAT
Mary         2    SUN
© www.soinside.com 2019 - 2024. All rights reserved.