pandas - 如何为 "start_date"列和 "end_date"列中的每一行创建 pandas.date_range() ?

标签 pandas date date-range

我有一个像这样的 df:

id | start_date | end_date  | price
1  | 2020-10-01 | 2020-10-3 | 1
1  | 2020-10-03 | 2020-10-4 | 1
2  | 2020-10-04 | 2020-10-6 | 2
3  | 2020-10-05 | 2020-10-5 | 3

列“start_date”和“end_date”为 datetime64[ns]。

我想从日期范围创建一个“日期”列。

最简单的方法是创建 pandas.date_range(start_date, end_date, freq="D"),然后使用 .explode()。

最终结果应如下所示:

id | start_date | end_date  | price | date
1  | 2020-10-01 | 2020-10-3 | 1     | 2020-10-01
1  | 2020-10-01 | 2020-10-3 | 1     | 2020-10-02
1  | 2020-10-01 | 2020-10-3 | 1     | 2020-10-03
1  | 2020-10-03 | 2020-10-4 | 1     | 2020-10-03
1  | 2020-10-03 | 2020-10-4 | 1     | 2020-10-04
2  | 2020-10-04 | 2020-10-6 | 2     | 2020-10-04
2  | 2020-10-04 | 2020-10-6 | 2     | 2020-10-05
2  | 2020-10-04 | 2020-10-6 | 2     | 2020-10-06
3  | 2020-10-05 | 2020-10-5 | 3     | 2020-10-05

到目前为止尝试过:

df["daterange"] = pd.date_range(df["start_date"], df["end_date"])

TypeError: Cannot convert input [0 2020-10-01 1 2020-10-01

for row in df.itertuples():
    df["daterange"] = pd.date_range(start=row.start_date, end=row.end_date)

ValueError: Length of values (3) does not match length of index (9)

Lambda、apply、melt 等对于我的数据帧大小来说太慢并且无法使用!

/编辑

我目前找到的Fastet方法:

https://github.com/Garve/scikit-bonus
skbonus.pandas.preprocessing.DateTimeExploder(
        "date",
        start_column="start_date",
        end_column="end_date",
        frequency="d",
        drop=False,
    )

最佳答案

使用DataFrame.apply :

df["daterange"] = df.apply(lambda x: pd.date_range(x.start_date, x.end_date), axis=1)
df = df.explode('daterange').reset_index(drop=True)
print (df)
   id  start_date   end_date  price  daterange
0   1  2020-10-01  2020-10-3      1 2020-10-01
1   1  2020-10-01  2020-10-3      1 2020-10-02
2   1  2020-10-01  2020-10-3      1 2020-10-03
3   1  2020-10-03  2020-10-4      1 2020-10-03
4   1  2020-10-03  2020-10-4      1 2020-10-04
5   2  2020-10-04  2020-10-6      2 2020-10-04
6   2  2020-10-04  2020-10-6      2 2020-10-05
7   2  2020-10-04  2020-10-6      2 2020-10-06
8   3  2020-10-05  2020-10-5      3 2020-10-05

替代方案:

s = pd.concat([pd.Series(r.Index,pd.date_range(r.start_date, r.end_date)) for r in df.itertuples()])
s = pd.Series(s.index, s)

df = df.join(s.rename('daterange')).reset_index(drop=True)
print (df)
   id  start_date   end_date  price  daterange
0   1  2020-10-01  2020-10-3      1 2020-10-01
1   1  2020-10-01  2020-10-3      1 2020-10-02
2   1  2020-10-01  2020-10-3      1 2020-10-03
3   1  2020-10-03  2020-10-4      1 2020-10-03
4   1  2020-10-03  2020-10-4      1 2020-10-04
5   2  2020-10-04  2020-10-6      2 2020-10-04
6   2  2020-10-04  2020-10-6      2 2020-10-05
7   2  2020-10-04  2020-10-6      2 2020-10-06
8   3  2020-10-05  2020-10-5      3 2020-10-05

关于pandas - 如何为 "start_date"列和 "end_date"列中的每一行创建 pandas.date_range() ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66689956/

相关文章:

python - 仅替换 pandas 中数据框行的第一个最大值?

python - 当函数应用于行时, Pandas 的 .groupby 函数出现奇怪的问题

python - 在 Python 中使用周期性正态分布 (von Mises) 提取时间特征

swift - 如何在 Swift 4 中显示日期而不包含年份?

java - 将 Thymeleaf 中的当前日期发送到变量

c++ - 如何检查一个范围内的值是否是另一个范围内的值的倍数?

python - 获取已排序的 numpy 矩阵或 pandas 数据帧的最后一个非 nan 索引

date - meteor /JS 日期

r - 多次有效地子集 data.table

PHP MYSQL 在这些日期之间使用此值选择 *