基于pandas中的两个条件进行分组和聚合的最有效方法

时间:2017-04-10 11:11:23

标签: python pandas dataframe

我有以下数据框:

user_id  sale     date        refunded
  1      1000    '2016-10-02'   0  
  1      1000    '2016-09-13'   0
  2      1000    '2016-08-11'   0
  2      1000    '2016-10-21'   0
  3      1000    '2016-11-01'   1
  3      1000    '2016-11-01'   1

我需要按user_id进行分组,并根据以下两个条件计算销售总额:

   date >='2016-10-01'
   refunded==0

我采取了两种不同的方法:

    non_refunded = df.refunded == 0
    after_assignment = df.date > '2016-10-01'
    columns = ['user_id', 'sale']
    tt = tdf.loc[non_refunded & after_assignment][columns].groupby(['user_id']).sum().reset_index()

另一种方法是:

columns = ['user_id', 'sale']
tt = df.loc[(df.refunded == 0) & (df.date > '2016-10-01')][columns].groupby(['user_id']).sum().reset_index()

在第一种方法中首先我创建了两个复制数据帧(我不确定它们是否是复制品)然后应用条件。你是否在速度,所需资源方面比较这两种方法,当这两种方法开始显示它们时差异,例如,如果我们应该为30行或更多行的30个不同数据帧执行此操作。

2 个答案:

答案 0 :(得分:2)

您使用的是IPython解释器吗?如果是这样,您可以使用%timeit魔法来衡量执行一行代码所需的时间。你有两种方法似乎做同样的事情 - 我不希望有任何性能差异。

为了便于阅读,我会使用第二种方法:

%timeit df.loc[(df.refunded == 0) & (df.date > '2016-10-01')].groupby('user_id').sum()

Pandas不会在相当现代的笔记本电脑上使用100k行数据帧。

答案 1 :(得分:1)

我认为您可以使用query

df.date = pd.to_datetime(df.date)
columns = ['user_id', 'sale']
filtered = df.query('refunded == 0 and date > "2016-10-01"')
tt = filtered[columns].groupby(['user_id']).sum().reset_index()
print (tt)
   user_id  sale
0        1  1000
1        2  1000

删除了另一个解决方案][并将列添加到loc

df.date = pd.to_datetime(df.date)
columns = ['user_id', 'sale']
filtered = df.loc[(df.refunded == 0) & (df.date > '2016-10-01'), columns]
tt = filtered[columns].groupby(['user_id']).sum().reset_index()
print (tt)
   user_id  sale
0        1  1000
1        2  1000