【发布时间】:2021-09-16 02:34:23
【问题描述】:
任务
我有一个如下所示的数据框:
| date | money_spent ($) | meals_eaten | weight |
|---|---|---|---|
| 2021-01-01 10:00:00 | 350 | 5 | 140 |
| 2021-01-02 18:00:00 | 250 | 2 | 170 |
| 2021-01-03 12:10:00 | 200 | 3 | 160 |
| 2021-01-04 19:40:00 | 100 | 1 | 150 |
我想对此进行离散化,以便它每隔$X“切割”行。我想知道一些关于我花费的每一个$X 完成了多少的统计数据。
因此,如果我使用$500 作为阈值,前两行将落在第一次剪切中,我可以将剩余的列聚合如下:
- 剪辑的第一个
date - 平均
meals_eaten - 最小
weight - 最大
weight
所以最终表格将是这样的两行:
| date | cumulative_spent ($) | meals_eaten | min_weight | max_weight |
|---|---|---|---|---|
| 2021-01-01 10:00:00 | 600 | 3.5 | 140 | 170 |
| 2021-01-03 12:10:00 | 300 | 2 | 150 | 160 |
我的方法:
我的第一个直觉是计算money_spent的cumsum()(假设数据是按日期排序的),然后我用pd.cut()基本上新建一个列,我们称之为spent_bin,这决定了每一行的 bin。
注意:在这个玩具示例中,spent_bin 基本上是:[0,500] 用于前两行,(500-1000] 用于后两行。
那么就比较简单了,我做一个groupbyspent_bin然后聚合如下:
.agg({
'date':'first',
'meals_eaten':'mean',
'returns': ['min', 'max']
})
我的尝试
import pandas as pd
rows = [
{"date":"2021-01-01 10:00:00","money_spent":350, "meals_eaten":5, "weight":140},
{"date":"2021-01-02 18:00:00","money_spent":250, "meals_eaten":2, "weight":170},
{"date":"2021-01-03 12:10:00","money_spent":200, "meals_eaten":3, "weight":160},
{"date":"2021-01-05 22:07:00","money_spent":100, "meals_eaten":1, "weight":150}]
df = pd.DataFrame.from_dict(rows)
df['date'] = pd.to_datetime(df.date)
df['cum_spent'] = df.money_spent.cumsum()
print(df)
print(pd.cut(df.cum_spent, 500))
由于某种原因,我无法让cut 步骤工作。这是我上面的toy code。由于某种原因,标签不干净[0-500], (500,1000]。老实说,我会满足于[350,500],(500-800](这是削减边缘的实际 cum sum 值),但即使我正在做与文档示例完全相同的操作,我什至无法让它工作.有什么帮助吗?
注意事项和困难:
当然,在 for 循环中编写它很容易,只需执行 while cum_spent < 500:。问题是我的实际数据集中有数百万行,目前以这种方式处理单个 df 需要 20 分钟。
还有一个小问题,有时行会打破间隔。发生这种情况时,我希望包括最后一行。这个问题出现在玩具示例中,其中第 2 行实际上以 600 美元而不是 500 美元结束。但它是结束于或超过 500 美元的第一行,所以我将它包含在第一个 bin 中。
【问题讨论】:
标签: python pandas dataframe vectorization