Python 熊猫:聚合后在分组键上加入 我所拥有的

Python 熊猫:聚合后在分组键上加入 我所拥有的,python,pandas,pandas-groupby,Python,Pandas,Pandas Groupby,我有这样一个熊猫架: df1 = pd.DataFrame({ 'date': ['31-05-2017', '31-05-2017', '31-05-2017', '31-05-2017', '01-06-2017', '01-06-2017'], 'tag': ['A', 'B', 'B', 'B', 'A', 'A'], 'metric1': [0, 0, 0, 1, 1, 1], 'metric2': [0, 1, 1, 0, 1, 0] })

我有这样一个熊猫架:

df1 = pd.DataFrame({
    'date': ['31-05-2017', '31-05-2017', '31-05-2017', '31-05-2017', '01-06-2017', '01-06-2017'],
    'tag':     ['A', 'B', 'B', 'B', 'A', 'A'],
    'metric1': [0, 0, 0, 1, 1, 1],
    'metric2': [0, 1, 1, 0, 1, 0]
})


df2 = pd.DataFrame({
    'date': ['31-05-2017', '31-05-2017', '01-06-2017'],
    'tag':     ['A', 'B', 'A'],
    'metric3': [25, 3, 7,]
})
我想要什么 1) 我想对
日期
标记

date       | tag | metric1_sum | metric2_sum | metric2_percentage| metric 3
-----------|-----|-------------|-------------|-------------------|---------
31-05-2017 | A   | 0           | 0           | 0                 | 25
31-05-2017 | B   | 1           | 2           | 0.667             | 3
01-06-2017 | A   | 1           | 0           | 0.5               | 7
2) 计算
metric_2

3) 将分组的df1与df2合并,以便我对每个
日期
标记

date       | tag | metric1_sum | metric2_sum | metric2_percentage| metric 3
-----------|-----|-------------|-------------|-------------------|---------
31-05-2017 | A   | 0           | 0           | 0                 | 25
31-05-2017 | B   | 1           | 2           | 0.667             | 3
01-06-2017 | A   | 1           | 0           | 0.5               | 7
尝试 (1) 集体和集体工作 (2) 计算百分比是可行的,但将其作为列添加则不行 我用这个方法来计算百分比

>>> g2 = df1.groupby(['date', 'tag']).agg({'metric2': 'sum'})
>>> g2.groupby(level=0).apply(lambda x: x/float(x.sum()))
                metric2
date       tag         
01-06-2017 A        1.0
31-05-2017 A        0.0
           B        1.0
cols = ['date', 'tag']
d1 = df1.groupby(cols).agg(
    dict(metric1='sum', metric2=['sum', 'mean'])
)

d1.columns = d1.columns.map('_'.join)

d1.join(df2.set_index(cols))

         date tag  metric1_sum  metric2_sum  metric2_mean  metric3
0  01-06-2017   A            2            1      0.500000        7
1  31-05-2017   A            0            0      0.000000       25
2  31-05-2017   B            1            2      0.666667        3
但是,我现在如何将此分组的
metric2
分配给我的组
g
或我的
df1
中的列
metric2\u百分比

(3) 合并失败 与集团合并显然不起作用:

>>> pd.merge(g, df2, how='left', on=['date', 'tag'])
KeyError: 'date'

然后如何将
df1
减少到每组一行,以便将其与
df2
合并?

g
日期、标记作为索引,而
合并
需要列,您需要在
g
上重置索引:

pd.merge(g.reset_index(), df2, how='left', on=['date', 'tag'])
或者指定
left\u index=True

pd.merge(g, df2, how='left', left_index=True, right_on=['date', 'tag'])
两者的结果如下(列顺序略有不同):


这里有一个替代方案,可以通过减少一个连接来完成您的工作:

(df1.groupby(['date', 'tag']).apply(
        lambda g: pd.Series({'metric1_sum': g.metric1.sum(), 
                             'metric2_sum': g.metric2.sum(), 
                             'metric2_percentage': g.metric2.mean()})   
# assumed here you have only 1 and 0 in metric 2 column if not use your own lambda function
    ).reset_index().merge(df2, how='left', on=['date', 'tag']))

#         date  tag  metric1_sum    metric2_percentage  metric2_sum metric3
#0  01-06-2017    A          2.0              0.500000         1.0        7
#1  31-05-2017    A          0.0              0.000000         0.0       25
#2  31-05-2017    B          1.0              0.666667         2.0        3

使用
agg
<代码>1和0的平均值将与百分比相同

>>> g2 = df1.groupby(['date', 'tag']).agg({'metric2': 'sum'})
>>> g2.groupby(level=0).apply(lambda x: x/float(x.sum()))
                metric2
date       tag         
01-06-2017 A        1.0
31-05-2017 A        0.0
           B        1.0
cols = ['date', 'tag']
d1 = df1.groupby(cols).agg(
    dict(metric1='sum', metric2=['sum', 'mean'])
)

d1.columns = d1.columns.map('_'.join)

d1.join(df2.set_index(cols))

         date tag  metric1_sum  metric2_sum  metric2_mean  metric3
0  01-06-2017   A            2            1      0.500000        7
1  31-05-2017   A            0            0      0.000000       25
2  31-05-2017   B            1            2      0.666667        3

为了一艘班轮而过度设计

from collections import OrderedDict

df1.groupby(['date', 'tag']).agg(
    dict(metric1='sum', metric2=['sum', 'mean'])
).pipe(
    lambda d: pd.DataFrame(OrderedDict({'_'.join(k): v for k, v in d.iteritems()}))
).join(df2.set_index(['date', 'tag'])).reset_index()

         date tag  metric1_sum  metric2_sum  metric2_mean  metric3
0  01-06-2017   A            2            1      0.500000        7
1  31-05-2017   A            0            0      0.000000       25
2  31-05-2017   B            1            2      0.666667        3

你能解释一下计算%和合并之间的问题吗?这些是独立的问题吗?太好了,我没有意识到我可以用reset_index()将组扁平化