为所有可能的组合创建一行

时间:2019-01-22 22:11:43

标签: python-3.x pandas

我有一个数据框,其中包含许多分类项,其中一些有一个月,而有些则没有。为了获得准确的平均值,我想找到一种方法来为每个月的每个类别创建空行值,然后填写其余部分。

数据如下:

 skinny_month
       month  Amount                Category
0    2019-01   18.34       Rental Car & Taxi
1    2019-01    7.95               Fast Food
2    2019-01   27.63             Restaurants
3    2019-01   69.00                     Gym
4    2019-01   20.60              Air Travel

...      ...     ...                     ...

1116 2013-04   10.00             Restaurants

我想返回的内容是:

skinny_month.groupby('Category')。mean()

                            Amount  Notes
Category                                 
ATM Fee                   2.600000    0.0
Advertising               6.486667    0.0
Air Travel              546.166250    0.0
Books                    17.631538    0.0
Business Services         9.746923    0.0

每月除外,因此我可以计算出实际的每月支出。问题在于,这使我似乎平均花费比实际更多,因为例如我的广告总费用是这样的:

skinny_month.groupby(['Category','month']).mean()
                             Amount
Category       month               
ATM Fee        2017-10     3.000000
...            ...         ...
Advertising    2018-06    15.340000
               2018-10     9.115000
               2018-11     5.350000

因此,由于2017年或2019年没有支出,因此应该更像是1.10(考虑到两年内的总支出为28美元,等等),但平均值只有三个月以上,因此显示为6.48。

我有一个带有正确日期的早期版本,并且使用过:

monthly_totals = non_savings.set_index('Category').resample('M', 'sum').fillna(method='ffill')

产生了

                                               Amount  Notes
Date       Category               Date                      
2013-02-16 Business Services      2013-02-28    65.00    0.0
           Restaurants            2013-02-28    35.00    0.0

2019-01-16 Air Travel             2019-01-31    20.60    0.0
2019-01-17 Gym                    2019-01-31    69.00    0.0
2019-01-19 Restaurants            2019-01-31    27.63    0.0

我觉得应该有一个简单的方法来为每个类别生成日期,但是填充似乎无法正常工作,因为它需要正确的开始和结束日期,此外,由于数据仅涵盖2013、2017、2018 ,以及从2019年初开始,由于我没有2014-2016年的任何记录,因此将其提前填补会过多地减少支出,因此这会使广告示例下降到0.34,这也不对。

我尝试进行concat调用,感觉应该有某种方式可以进行逐行迭代,但我无法弄清楚。任何帮助都欢迎。

1 个答案:

答案 0 :(得分:1)

研究pd.MultiIndex.from_product可能应该归功于您的追求。

类似这样的一些变化:

In [24]: x = pd.date_range('2019-01-01', '2019-04-01', freq='MS')

In [25]: y = ['a', 'b', 'c']

In [26]: index = pd.MultiIndex.from_product([x, y])

In [27]: for ix in index:
    ...:     print(ix)
    ...: 
    ...: 
    ...: 
(Timestamp('2019-01-01 00:00:00', freq='MS'), 'a')
(Timestamp('2019-01-01 00:00:00', freq='MS'), 'b')
(Timestamp('2019-01-01 00:00:00', freq='MS'), 'c')
(Timestamp('2019-02-01 00:00:00', freq='MS'), 'a')
(Timestamp('2019-02-01 00:00:00', freq='MS'), 'b')
(Timestamp('2019-02-01 00:00:00', freq='MS'), 'c')
(Timestamp('2019-03-01 00:00:00', freq='MS'), 'a')
(Timestamp('2019-03-01 00:00:00', freq='MS'), 'b')
(Timestamp('2019-03-01 00:00:00', freq='MS'), 'c')
(Timestamp('2019-04-01 00:00:00', freq='MS'), 'a')
(Timestamp('2019-04-01 00:00:00', freq='MS'), 'b')
(Timestamp('2019-04-01 00:00:00', freq='MS'), 'c')