熊猫对时间和组的滚动条件和



我有一个显然很难的任务要做,在Python/Pandas。我有一个像这样的数据框架:

| DATETIME | PRODUCT | AMOUNT |

我需要生成最后一列,其中包含每个产品(我有两个以上的产品)在过去5分钟内(假设售出的产品)金额的累计总和。请看下面的例子:

| DATETIME              | PRODUCT | AMOUNT | CUM SUM        |
| 2020-01-01 17:10:00   | A       | 20     | 20 -> 20       |
| 2020-01-01 17:12:00   | B       | 30     | 30 -> 30       |
| 2020-01-01 17:13:00   | A       | 10     | 20+10 -> 30    |
| 2020-01-01 17:13:00   | A       | 15     | 20+10+15 -> 45 |
| 2020-01-01 17:16:00   | B       | 10     | 30+10 -> 40    |
| 2020-01-01 17:17:00   | A       | 15     | 10+15+15 -> 40 |
| 2020-01-01 17:20:00   | B       | 20     | 10+20 -> 30    |
| 2020-01-01 17:20:00   | B       | 10     | 10+20+10 -> 40 |
| 2020-01-01 17:25:00   | A       | 10     | 10 -> 10       |

注意,couple (datetime, product)可能不是唯一的,但是我仍然需要根据数据框架索引保持一个顺序。

I tried with:

  1. 滚动功能:但不幸的是,我没有固定的窗口大小,我没有唯一的夫妇(日期时间,产品),所以我不能使用日期时间作为索引,然后使用.rolling('5 minutes')
  2. Groupby(product).cumsum():但是我不能把总和限制在最后几分钟。

可能,我需要一些平滑的,在性能水平上不太糟糕的东西,来应用在一个相当大的df上。

你有什么提示吗?

提前谢谢你。

您可以使用pd.DataFrame.groupby,groupby.apply,pd.DataFrame.rolling的时间窗口(5分钟== '5T')和rolling.sum:

>>> df['CUM SUM'] = (df.set_index('DATETIME')
.groupby('PRODUCT')
.apply(lambda x: x.rolling('5T').sum()
).values)
DATETIME PRODUCT  AMOUNT  CUM SUM
0 2020-01-01 17:10:00       A      20     20.0
1 2020-01-01 17:12:00       B      30     30.0
2 2020-01-01 17:13:00       A      10     30.0
3 2020-01-01 17:13:00       A      15     45.0
4 2020-01-01 17:16:00       B      10     40.0
5 2020-01-01 17:17:00       A      15     40.0
6 2020-01-01 17:20:00       B      20     30.0
7 2020-01-01 17:20:00       B      10     40.0
8 2020-01-01 17:25:00       A      10     10.0

我正在添加确切的步骤,看看你是否能发现你的df有什么不同:

>>> from io import StringIO
>>> df = pd.read_csv(StringIO("""
DATETIME               PRODUCT  AMOUNT
2020-01-01 17:10:00    A        20
2020-01-01 17:12:00    B        30
2020-01-01 17:13:00    A        10
2020-01-01 17:13:00    A        15
2020-01-01 17:16:00    B        10
2020-01-01 17:17:00    A        15
2020-01-01 17:20:00    B        20
2020-01-01 17:20:00    B        10
2020-01-01 17:25:00    A        10"""), sep=r'ss+')
>>> df['DATETIME'] = pd.to_datetime(df['DATETIME'])
>>> df
DATETIME PRODUCT  AMOUNT
0 2020-01-01 17:10:00       A      20
1 2020-01-01 17:12:00       B      30
2 2020-01-01 17:13:00       A      10
3 2020-01-01 17:13:00       A      15
4 2020-01-01 17:16:00       B      10
5 2020-01-01 17:17:00       A      15
6 2020-01-01 17:20:00       B      20
7 2020-01-01 17:20:00       B      10
8 2020-01-01 17:25:00       A      10
>>> df['CUM SUM'] = (df.set_index('DATETIME')
.groupby('PRODUCT')
.apply(lambda x: x.rolling('5T').sum()
).values)
>>> df
DATETIME PRODUCT  AMOUNT  CUM SUM
0 2020-01-01 17:10:00       A      20     20.0
1 2020-01-01 17:12:00       B      30     30.0
2 2020-01-01 17:13:00       A      10     30.0
3 2020-01-01 17:13:00       A      15     45.0
4 2020-01-01 17:16:00       B      10     40.0
5 2020-01-01 17:17:00       A      15     40.0
6 2020-01-01 17:20:00       B      20     30.0
7 2020-01-01 17:20:00       B      10     40.0
8 2020-01-01 17:25:00       A      10     10.0

我注意到我错过了值后面的右括号,固定。

编辑

适用于pandas 1.2.0, for ' pandas 1.0.5':

>>> df['CUM SUM'] = (df.set_index('DATETIME')
.groupby('AMOUNT')
.apply(lambda x: x.rolling('5T').sum().reset_index(drop=True))
.values)

最新更新