Pandas中具有缺失值的时间相关数据集的平均值

时间:2014-01-14 14:15:14

标签: python numpy pandas

对于我正在研究的项目,我需要计算商店产品的平均价格。每次商店更改产品的价格时,都会向数据集添加新条目。如果商店停止(暂时或永久)销售产品,则使用时间戳和价格值-1进行输入。例如:

          timestamp     shop  product    price

2014-01-01 10:07:32        E        4    19.99
2014-01-01 10:07:32        F        5    54.00
2014-01-02 14:41:12        A        1    28.00
2014-01-02 14:41:12        D        3   249.99
2014-01-02 15:12:38        C        1    29.99
2014-01-03 14:05:12        B        2    43.00
2014-01-05 12:21:57        F        5    49.99
2014-01-06 23:55:32        F        5    -1
2014-01-07 03:05:12        B        2    39.99
2014-01-07 11:24:49        D        3    -1
2014-01-08 11:35:33        C        2    40.99
2014-01-08 16:28:07        F        5    65.00
2014-01-12 21:41:04        E        3   199.00

测试用例:

  • 购买:在计算时间段内没有产品1的价格输入的商品
  • 在此期间内具有产品2开关价格的商店B
  • 在此期间开始销售产品2的商店C,并通过
  • 销售产品1
  • 在此期间停止销售产品3的商店D.
  • 商店E开始销售产品3并在此期间销售产品4
  • 购买F,产品5改变价格,然后停止销售,然后以新价格重新开始,全部在此期间

平均值的期间为2014-01-05 00:00:00至2014-01-10 23:59:59

我需要做的是计算某个商店在一定时期内的平均价格。这是平均时间加权(3天1天和1天价格1的平均值是4天的平均值2.5而不是1.5)。我有两个问题:

  • 可能缺少起始值。最后的价格变化我最有可能在计算的时间段的乞讨,所以我需要找到一种方法来填补它,以便它将在平均使用。事实上,这可能是整个时期内唯一的价格。
  • 使用-1计算会得到错误的结果。应忽略该值,并且应在产品不再可用的时间内减少总时间增量。

上面给出的数据的预期输出是(价格四舍五入到最接近的分数):

shop   product    price
   A         1    28.00
   B         2    41.06
   C         1    29.99
   C         2    40.99
   D         3   249.99
   E         4    19.99
   F         5    53.81

我尝试使用numpy.ma来屏蔽-1值。但是,由于isnanmasked_less无法解决此问题,因此我未能成功执行此操作。

有关如何实现这一目标的任何想法吗?

编辑: 编辑测试数据预期结果可以更清楚地反映问题

2 个答案:

答案 0 :(得分:0)

AFAIR,pandas无法以numpy.ma方式处理屏蔽值。但是,它应该在计算均值时处理nans。 最简单的解决方案是解析您的Dataframe并将-1.00的价格替换为np.nan,例如:

price = dataframe['price']
price[price == -1] = np.nan

答案 1 :(得分:0)

我不清楚你到底需要什么。似乎一个简单的groupby可以解决这个问题:

import StringIO
import numpy as np
import pandas

datatext = StringIO.StringIO("""\
          timestamp                              shop  product   price
2014-01-02 14:41:12  3075774DFBB0014CC1257822003CE79B  1135972   28.00
2014-01-03 14:05:12  3075774DFBB0014CC1257822003CE79B  1129779   43.00
2014-01-03 20:49:12  FDB140FB8F5FB469C125713B0035474F  1643094  145.00
2014-01-04 07:26:12  3075774DFBB0014CC1257822003CE79B  1080521   27.00
2014-01-05 10:44:12  949BC26900E5E48BC125773D00520641  1149009   59.99
2014-01-06 13:21:53  FDB140FB8F5FB469C125713B0035474F  1644526   -1.00
2014-01-06 15:28:53  FDB140FB8F5FB469C125713B0035474F  1643094   -1.00
2014-01-06 13:21:53  00000000000000000000000001262068  1742831   -1.00
2014-01-07 12:00:10  9D973A188A017E3DC1256C220034A923  1067842   31.99
2014-01-09 12:25:54  78F58D53EA47E73AC12575F4004A42AA   232979  129.00
""")
df = pandas.read_table(datatext, index_col=[0], parse_dates=True, sep='\s\s+')

# mask out the negative values
df['price'][df['price'] < 0] = np.nan

# group by the shop and product and compute the mean
df.groupby(by=['shop', 'product']).mean()

这给了我:

                                           price
shop                             product        
00000000000000000000000001262068 1742831     NaN
3075774DFBB0014CC1257822003CE79B 1080521   27.00
3075774DFBB0014CC1257822003CE79B 1129779   43.00
3075774DFBB0014CC1257822003CE79B 1135972   28.00
78F58D53EA47E73AC12575F4004A42AA 232979   129.00
949BC26900E5E48BC125773D00520641 1149009   59.99
9D973A188A017E3DC1256C220034A923 1067842   31.99
FDB140FB8F5FB469C125713B0035474F 1643094  145.00
FDB140FB8F5FB469C125713B0035474F 1644526     NaN