Python 过滤多列groupby结果,以获得

Python 过滤多列groupby结果,以获得,python,pandas,Python,Pandas,使用Pandas,我将如何过滤数据帧,以便只显示当天事务总数>N的天数 import pandas as pd data = [ ["2017-01-01 00:00:01.012345", 'Jen', 1.01], ["2017-01-01 01:00:00.012345", 'Joe', 3.02], ["2017-02-01 00:00:00.012345", 'Jen', 2.02], ["2017-02-01 02:00:00.012345", 'Jo

使用Pandas,我将如何过滤数据帧,以便只显示当天事务总数>N的天数

import pandas as pd
data = [
    ["2017-01-01 00:00:01.012345", 'Jen', 1.01],
    ["2017-01-01 01:00:00.012345", 'Joe', 3.02],
    ["2017-02-01 00:00:00.012345", 'Jen', 2.02],
    ["2017-02-01 02:00:00.012345", 'Joe', 0.02],
    ["2017-03-01 03:00:00.012345", 'Jen', 3.02],
    ["2017-03-01 04:00:00.012345", 'Joe', 4.04],
    ["2017-03-01 05:00:01.012345", 'Jen', 5.01]]
df = pd.DataFrame({
    'trx_time': list(zip(*data))[0],
    'agent': list(zip(*data))[1],
    'trx_amount': list(zip(*data))[2]})
df['day'] = df['trx_time'].apply(lambda x: pd.to_datetime(x).date())
grouped = df.groupby(['day', 'agent'])
by_day_df = grouped.aggregate('sum')\
    .rename(columns = lambda x: 'day_tl_' + x)\
    .join(pd.DataFrame(grouped.size(), columns=['trx_count']))
print (by_day_df)
输出:

day        agent                              
2017-01-01 Jen                 1.01          1
           Joe                 3.02          1
2017-02-01 Jen                 2.02          1
           Joe                 0.02          1
2017-03-01 Jen                 8.03          2
           Joe                 4.04          1
因此,在筛选之后,我不希望2017-02-01的任何一行显示为当天的总数<3


是否可以使用.filter()完成此操作?

我认为您可以按索引的第一级删除行,并聚合
sum
,最后删除这些行:

df1 = by_day_df.groupby(level=0)['day_tl_trx_amount'].sum()
idx = df1[df1 < 3].index
print (idx)
Index([2017-02-01], dtype='object', name='day')

print (by_day_df.drop(idx, level=0))
                  day_tl_trx_amount  trx_count
day        agent                              
2017-01-01 Jen                 1.01          1
           Joe                 3.02          1
2017-03-01 Jen                 8.03          2
           Joe                 4.04          1
还对代码进行了一些改进,主要用于从
系列
创建
数据帧

#vectorized to_datetime and then dt.date
df['day'] = pd.to_datetime(df['trx_time']).dt.date

grouped = df.groupby(['day', 'agent'])
by_day_df = grouped.trx_amount.sum().to_frame() \
                   .rename(columns = lambda x: 'day_tl_' + x)\
                   .join(grouped.size().to_frame('trx_count'))
print (by_day_df)
  agent  trx_amount                    trx_time
0   Jen        1.01  2017-01-01 00:00:01.012345
1   Joe        3.02  2017-01-01 01:00:00.012345
2   Jen        2.02  2017-02-01 00:00:00.012345
3   Joe        0.02  2017-02-01 02:00:00.012345
4   Jen        3.02  2017-03-01 03:00:00.012345
5   Joe        4.04  2017-03-01 04:00:00.012345
6   Jen        5.01  2017-03-01 05:00:01.012345
  • 重要的部分是将
    groupby
    索引的第一级,并取列
    day\u tl\u trx\u金额的总和
  • 然后,我们需要仅按总和大于或等于
    3
    3的天数过滤分组和汇总的数据
  • 最后,我们使用这些天来过滤第一个数据帧

查找总和>=3的天数

idx = by_day_df.groupby(level='day')[['day_tl_trx_amount']].sum() \
    .query('day_tl_trx_amount >= 3').index.tolist()
by_day_df.loc[idx]

                  day_tl_trx_amount  trx_count
day        agent                              
2017-01-01 Jen                 1.01          1
           Joe                 3.02          1
2017-03-01 Jen                 8.03          2
           Joe                 4.04          1
筛选第一个数据帧

idx = by_day_df.groupby(level='day')[['day_tl_trx_amount']].sum() \
    .query('day_tl_trx_amount >= 3').index.tolist()
by_day_df.loc[idx]

                  day_tl_trx_amount  trx_count
day        agent                              
2017-01-01 Jen                 1.01          1
           Joe                 3.02          1
2017-03-01 Jen                 8.03          2
           Joe                 4.04          1

使用
unstack
sum

我的首选解决方案

s = by_day_df.unstack().day_tl_trx_amount.sum(1).ge(3)
by_day_df.loc[s.index[s].tolist()]

                  day_tl_trx_amount  trx_count
day        agent                              
2017-01-01 Jen                 1.01          1
           Joe                 3.02          1
2017-03-01 Jen                 8.03          2
           Joe                 4.04          1

我已尝试使用mask解决此问题:

by_day_df.reset_index(inplace=True)
mask=by_day_df.groupby('day')['day_tl_trx_amount'].sum()>3
by_day_df.set_index('day',inplace=True)
by_day_df=by_day_df[mask]
by_day_df.reset_index(inplace=True)
by_day_df.set_index(['day','agent'],inplace=True)