我的数据如下:
...
A B C
2017-09-18 12:00:00 1.000010 18000 100
2017-09-18 17:00:00 1.000029 13500 400
2017-09-19 12:00:00 1.000025 18000 300
2017-09-19 17:00:00 1.000037 13500 300
...
在同一天的2个不同时间,分别测量A,B和C。
我需要每天将每2个小节折叠成一行(例如,对于前2行):
A和B列的加权平均值
((A1 * B1) + (A2 * B2)) / (B1 + B2)
C列的平均值
(C1 + C2) / 2
鉴于相邻行有不同的时间并且需要对列A B进行自定义操作(不同于C),因此尝试df.groupby
这些相邻行时会遇到困难。
我的预期输出是:
A C
2017-09-18 12:00:00 1.000018143 250
2017-09-19 12:00:00 1.000030143 300
任何指针将不胜感激。
答案 0 :(得分:4)
检查
df.groupby(df.index.date).apply(lambda x : pd.Series({'A':sum(x['A']*x['B'])/sum(x['B']),'C':(x['C']).mean()}))
A C
2017-09-18 1.000018 250.0
2017-09-19 1.000030 300.0
或者让我们不要使用Apply
t1=df.eval('A*B').groupby(df.index.date).sum()/df.groupby(df.index.date).B.sum()
t2=df.groupby(df.index.date).C.mean()
pd.concat([t1,t2],1)
0 C
2017-09-18 1.000018 250
2017-09-19 1.000030 300
答案 1 :(得分:4)
您可以使用groupby
,apply
和mean
将其向量化:
def AB_weighted(g):
return (g['A'] * g['B']).sum() / g['B'].sum()
g = df.groupby(df.index.date)
pd.concat([g.apply(AB_weighted), g['C'].mean()], keys=['A', 'C'], axis=1)
A C
2017-09-18 1.000018 250
2017-09-19 1.000030 300
apply
,因为groupby计算使用多个列-“ A”和“ B”。mean()
来缩短内容。另一种选择是在groupby
之前计算乘积,因此我们可以绕过对apply
的调用(这有点类似于@WB第二个答案),但是可以进行一次sum
调用。
u = df.assign(D=df['A'] * df['B'])[['D', 'B']].groupby(df.index.date).sum()
u['A'] = u.pop('D') / u.pop('B')
u['C'] = df.groupby(df.index.date)['C'].mean()
u
A C
2017-09-18 1.000018 250
2017-09-19 1.000030 300