我有一个数据框(称为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
有没有更好的方法来做我想做的事情?
答案 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,传递min
和max
日期值,然后在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
符合您条件的行数。