如何旋转熊猫数据框以包含加权平均值?

时间:2018-07-13 12:34:23

标签: python pandas

我在pandas数据框中有一些数据,其中date列是索引,如下所示:

date        value A       value B      country        category
ddmmyy      A1            B1           US             Red
ddmmyy      A2            B2           US             Red
ddmmyy      A3            B3           UK             Green
ddmmyy      A4            B4           UK             Green
ddmmyy      A5            B5           US             Red
ddmmyy      A6            B6           US             Red

有多个国家(英国,美国除外)和多个类别(红色和绿色除外)。这些日期代表交易,并且以不规则的频率发生。我想重新组合数据,如下所示:

date        UK           US    
mmyy       num11        num21
mmyy       num12        num22
mmyy       num13        num23
mmyy       num14        num24

哪里 1.日期是定期连续的每月日期 2.英国的num11是给定月份中A1xB1,A2xB2等的加权平均值,即weighted average for a given month = sum {An x Bn}除以给定月份中Bn的总和。美国也是如此。

我尝试使用例如

  

dataframe ['Val A']。resample('M',how ='sum')

通过对数字A(例如,每月A1,A2等。但是没有给我每个国家想要的加权平均值。

在Pandas / Python中最好的方法是什么?

2 个答案:

答案 0 :(得分:2)

这是一种groupbyapply的方法:

import pandas as pd
import numpy as np

def weighted_average(group):
    return (group["value A"] * group["value B"]).sum() / group["value B"].sum()


df = pd.DataFrame({"value A": np.random.randint(1, 100, 10),
                   "value B": np.random.randint(1, 100, 10),
                   "country": np.random.choice(["US", "UK"], 10),
                   "category": np.random.choice(["Red", "Green"], 10)},
                  index=pd.date_range("2018-01-26", "2018-02-04", num=10))
print(df)
#            category country  value A  value B
# 2018-01-26    Green      UK       74       93
# 2018-01-27    Green      UK       57        1
# 2018-01-28    Green      US        6       24
# 2018-01-29    Green      UK       31       89
# 2018-01-30    Green      UK       73       75
# 2018-01-31    Green      US       86       63
# 2018-02-01    Green      US       86       30
# 2018-02-02    Green      US       53       37
# 2018-02-03      Red      UK       50       69
# 2018-02-04      Red      US       98       33

print(df.groupby([pd.Grouper(freq='M'), "country"]).apply(weighted_average)).unstack()
# country            UK         US
# 2018-01-31  58.810078  63.931034
# 2018-02-28  50.000000  77.750000

请注意pandas.Grouper,它按月分组(默认情况下是索引,但是如果您不想设置索引,也可以在列中提供key="date")。< / p>

如果您还想同时按类别分开,则可以将其添加到groupby调用(df.groupby([pd.Grouper(freq='M'), "country", "category"])...)中。这将使索引更深一层,因此您必须确定是否要在列或行上使用多重索引。如果您希望在列上添加它,只需在末尾向unstack()添加另一个调用即可。

答案 1 :(得分:0)

我将创建一个新列mmyy-如果date列是日期或字符串,则可能必须使用datetime模块。 然后按mmyy分组,得到A和B的总和,然后创建一个刚好是A / B的新列