使用来自熊猫和字典的数据生成加权平均值?

时间:2019-05-13 18:18:48

标签: python pandas dictionary

我有一个数据框:

             SALES 
Date                       
2018-03-31  123090     
2018-04-30  116591      
2018-05-31  119581      
2018-06-30  117544      
2018-07-31  129574      
2018-08-31  118876      
2018-09-30  129467      
2018-10-31  126062     
2018-11-30  128552     
2018-12-31  104994     
2019-01-31  149188      
2019-02-28  118204      

还有一本字典,价格

{Oct: 11, Nov: 23, Dec: 34, Jan: 20, Feb: 30, Mar: 31, Apr: 22, May: 
23, Jun: 34, Jul: 20, Aug: 30, Sep: 31}

我想通过将DataFrame中每个销售数字与字典中相应的月份相乘,然后除以总销售数字来计算加权平均价格。即从数据框中获取10月 126062 的销售额,然后将其乘以字典中的11( Oct )。

我尝试添加月份列并重新排列数据框,然后使用有序字典,但是我感觉我在使用众所周知的八角锤来解决这个问题。

             SUM  MONTH
Date                       
2019-01-31  129188.1      1
2019-02-28  118304.5      2
2018-03-31  123090.6      3
2018-04-30  116591.2      4
2018-05-31  119581.5      5
2018-06-30  117544.0      6
2018-07-31  129574.9      7
2018-08-31  118876.2      8
2018-09-30  109467.5      9
2018-10-31  126062.0     10
2018-11-30  128552.9     11
2018-12-31  104994.2     12

我还尝试查看zip并在数据框和字典上进行迭代,但是我一直在努力寻找将两个数据集映射在一起的最佳方法。

如果很容易将字典转换为另一个数据框,我很高兴?

任何帮助将不胜感激。

4 个答案:

答案 0 :(得分:4)

您可以将map与DatetimeIndex方法strftime一起使用:

其中df,dataframe和dd的等待字典定义为

d = {'SALES': {pd.Timestamp('2018-03-31 00:00:00'): 123090,
  pd.Timestamp('2018-04-30 00:00:00'): 116591,
  pd.Timestamp('2018-05-31 00:00:00'): 119581,
  pd.Timestamp('2018-06-30 00:00:00'): 117544,
  pd.Timestamp('2018-07-31 00:00:00'): 129574,
  pd.Timestamp('2018-08-31 00:00:00'): 118876,
  pd.Timestamp('2018-09-30 00:00:00'): 129467,
  pd.Timestamp('2018-10-31 00:00:00'): 126062,
  pd.Timestamp('2018-11-30 00:00:00'): 128552,
  pd.Timestamp('2018-12-31 00:00:00'): 104994,
  pd.Timestamp('2019-01-31 00:00:00'): 149188,
  pd.Timestamp('2019-02-28 00:00:00'): 118204}}

df = pd.DataFrame(d)

dd = {'Oct': 11, 'Nov': 23, 'Dec': 34, 'Jan': 20, 'Feb': 30, 'Mar': 31, 'Apr': 22,'May': 
23, 'Jun': 34, 'Jul': 20, 'Aug': 30,'Sep': 31}

使用

df['Adj Sales'] = df.index.strftime('%b').map(dd) * df['SALES']

输出:

             SALES  Adj Sales
2018-03-31  123090    3815790
2018-04-30  116591    2565002
2018-05-31  119581    2750363
2018-06-30  117544    3996496
2018-07-31  129574    2591480
2018-08-31  118876    3566280
2018-09-30  129467    4013477
2018-10-31  126062    1386682
2018-11-30  128552    2956696
2018-12-31  104994    3569796
2019-01-31  149188    2983760
2019-02-28  118204    3546120

答案 1 :(得分:1)

尝试此操作以获取权重列:

my_dict = {'Oct': 11, 'Nov': 23, 'Dec': 34, 
           'Jan': 20, 'Feb': 30, 'Mar': 31, 
           'Apr': 22, 'May': 23, 'Jun': 34, 
           'Jul': 20, 'Aug': 30, 'Sep': 31}
weights = pd.Series(my_dict)

df.Date = pd.to_datetime(df.Date)
df.set_index(df.Date.dt.strftime("%b"),
             inplace=True)

df['Weights'] = weights

df.reset_index(drop=True, inplace=True)

然后df是:

    Date        SALES   Weights
0   2018-03-31  123090  31
1   2018-04-30  116591  22
2   2018-05-31  119581  23
3   2018-06-30  117544  34
4   2018-07-31  129574  20
5   2018-08-31  118876  30
6   2018-09-30  129467  31
7   2018-10-31  126062  11
8   2018-11-30  128552  23
9   2018-12-31  104994  34
10  2019-01-31  149188  20
11  2019-02-28  118204  30

答案 2 :(得分:0)

我会这样: 首先创建'weight'列:

df['weight'] = [month[ind_month] for ind_month in df.index.month_name().str[:3].values]

Out[48]:
            Sales  weight
2018-03-31    100      31
2018-04-30    101      22
2018-05-31    102      23
2018-06-30    103      34
2018-07-31    104      20
2018-08-31    105      30
2018-09-30    106      31
2018-10-31    107      11
2018-11-30    108      23
2018-12-31    109      34
2019-01-31    110      20
2019-02-28    111      30
2019-03-31    112      31
2019-04-30    113      22

其中:

 month = {'Oct': 11,'Nov': 23,'Dec': 34, 'Jan': 20, 'Feb': 30, 'Mar': 31,'Apr': 22, 'May': ^M
   ...: 23, 'Jun': 34, 'Jul': 20,'Aug': 30, 'Sep': 31}

然后多列:

df['weighted_Sales'] = df.weight * df.Sales

产生:

    Out[50]:
             Sales  weight  weighted_Sales
2018-03-31    100      31            3100
2018-04-30    101      22            2222
2018-05-31    102      23            2346
2018-06-30    103      34            3502
2018-07-31    104      20            2080
2018-08-31    105      30            3150
2018-09-30    106      31            3286
2018-10-31    107      11            1177
2018-11-30    108      23            2484
2018-12-31    109      34            3706
2019-01-31    110      20            2200
2019-02-28    111      30            3330
2019-03-31    112      31            3472
2019-04-30    113      22            2486

答案 3 :(得分:0)

步骤1.从字典中创建价格数据框

dict_p = {"Oct": 11, "Nov": 23, "Dec": 34, "Jan": 20, "Feb": 30, "Mar": 31, "Apr": 22, "May": 23, "Jun": 34, "Jul": 20, "Aug": 30, "Sep": 31}
dict_m = {"Oct": 10, "Nov": 11, "Dec": 12, "Jan": 1, "Feb": 2, "Mar": 3, "Apr": 4, "May": 5, "Jun": 6, "Jul": 7, "Aug": 8, "Sep": 9}

import pandas as pd

price = pd.DataFrame.from_dict(dict_p, orient = "index", columns = ["price"])
month = pd.DataFrame.from_dict(dict_m, orient = "index", columns = ["month"])

df_price = pd.concat([price, month],axis = 1)
print(df_price)

产生:

 price  month
Oct     11     10
Nov     23     11
Dec     34     12
Jan     20      1
Feb     30      2
Mar     31      3
Apr     22      4
May     23      5
Jun     34      6
Jul     20      7
Aug     30      8
Sep     31      9

第2步。合并价格和销售数据

df_sales = pd.DataFrame(d)
df_sales["month"] = df_sales.index.month

df = df_sales.merge(df_price)
print(df)

产生:

     SALES  month  price
0   123090      3     31
1   116591      4     22
2   119581      5     23
3   117544      6     34
4   129574      7     20
5   118876      8     30
6   129467      9     31
7   126062     10     11
8   128552     11     23
9   104994     12     34
10  149188      1     20
11  118204      2     30

第3步。计算权重并计算加权平均价格

df["weight"] = df.SALES/df.SALES.sum()
price_weighted_ave = sum(df.price*df.weight)
print(price_weighted_ave)

产生:

25.471658332900283