我在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中最好的方法是什么?
答案 0 :(得分:2)
这是一种groupby
和apply
的方法:
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的新列