如何在数据框中累计计算行数?

时间:2015-10-14 09:11:28

标签: python pandas group-by

我有一个数据框(称为u),其中一列(称为dates)包含日期。现在我想生成另一个数据框,其中包含u表中最小和最大日期之间的所有日期(每行对应一个日期)。在新数据框架中,我还希望有一个列,表明第一个表中有多少行具有较小的日期。

例如,第一个表就是这样:

| a | 2015-01-01 |
| b | 2015-01-01 |
| c | 2015-01-03 |
| d | 2015-01-04 |

然后第二个数据框必须是这样的:

| 2015-01-01 | 0 |
| 2015-01-02 | 2 |
| 2015-01-03 | 2 |
| 2015-01-04 | 3 |

我写了一个完全符合我需要的代码,但它非常慢而且不优雅。这就是我所拥有的:

min_date = u.dates.min()
max_date = u.dates.max()
dates = []
date = min_date
while True:
    dates.append(date)
    if date == max_date:
        break
    date = date + datetime.timedelta(days=1)

date2n = {}
for date in dates:
    n = len(u[u.dates < date]) 
    date2n[date] = n

有没有更好的方法来做我想做的事情?

2 个答案:

答案 0 :(得分:3)

以这种方式:

获取每个日期组的计数并获取累计总和:

In [3]: u1 = u.groupby('dates')['dates'].count().cumsum()

In [4]: u1
Out[4]: 
dates
2015-01-01    2
2015-01-03    3
2015-01-04    4
Name: dates, dtype: int64

这为我们提供了小于或等于给定日期的日期的计数,因此我们需要移动一天:

In [5]: u2 = u1.shift(1, freq='d')

In [6]: u2
Out[6]: 
dates
2015-01-02    2
2015-01-04    3
2015-01-05    4
Name: dates, dtype: int64

重新索引以获取范围内缺少的日期:

In [7]: u3 = u2.reindex(min_date, max_date)

In [8]: u3
Out[8]: 
2015-01-01   NaN
2015-01-02     2
2015-01-03   NaN
2015-01-04     3
Freq: D, Name: dates, dtype: float64

通过前向填充填写缺失值,并用0填充第一个条目:

In [9]: u4 = u3.fillna(method='ffill').fillna(0)

In [10]: u4
Out[10]: 
2015-01-01    0
2015-01-02    2
2015-01-03    2
2015-01-04    3
Freq: D, Name: dates, dtype: float64

答案 1 :(得分:2)

我使用date_range添加新的col,传递minmax日期值,然后在df上调用apply,其中一列传递param {{ 1}}到axis=1行,您可以使用sum计算符合条件的行数(因为这会将apply转换为True和{{ 1}}到1)并将其添加为新列:

False

修改

根据您的新信息:

0

因此,我构建了一个带日期范围的新df,您可以调用此方法并In [235]: df['date_range'] = pd.date_range(start=df['dates'].min(), end=df['dates'].max()) df ​ Out[235]: Col1 dates date_range 0 a 2015-01-01 2015-01-01 1 b 2015-01-01 2015-01-02 2 c 2015-01-03 2015-01-03 3 d 2015-01-04 2015-01-04 In [255]: df['count'] = df[['date_range']].apply(lambda x: (df['dates'] < x.values[0]).sum(), axis=1) df Out[255]: Col1 dates date_range count 0 a 2015-01-01 2015-01-01 0 1 b 2015-01-01 2015-01-02 2 2 c 2015-01-03 2015-01-03 2 3 d 2015-01-04 2015-01-04 3 符合您条件的行数。