Python 过滤多列groupby结果,以获得
使用Pandas,我将如何过滤数据帧,以便只显示当天事务总数>N的天数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
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)