从另一个给定的时间戳开始,在pandas系列中创建时间戳序列

时间:2018-07-13 10:09:54

标签: python pandas timestamp

假设我有一个名为df的数据框:

import pandas as pd
df = pd.DataFrame({"user_id": [2124, 18420],
                   "on_pm_at": [pd.Timestamp("2018-06-21 11:06:33.620913"),
                                pd.Timestamp("2018-02-24 04:56:48.175177")]})

+---------+----------------------------+
| user_id |          on_pm_at          |
+---------+----------------------------+
|    2124 | 2018-06-21 11:06:33.620913 |
|   18420 | 2018-02-24 04:56:48.175177 |
+---------+----------------------------+

我想创建一个新的数据框(假设new_df),其中每个用户都具有直到当前月份为止的月底日期的时间戳。例如,今天是7月13日,这个月底是7月31日,因此:

+---------+------------+
| user_id |   months   |
+---------+------------+
|    2124 | 2018-06-30 |
|    2124 | 2018-07-31 |
|   18420 | 2018-02-28 |
|   18420 | 2018-03-31 |
|   18420 | 2018-04-30 |
|   18420 | 2018-05-31 |
|   18420 | 2018-06-30 |
|   18420 | 2018-07-31 |
+---------+------------+

到目前为止,我最好的尝试(但看起来很丑)是:

df.groupby(["user_id", pd.Grouper(key = "on_pm_at", freq = 'M')]).agg({"user_id": "size"}).rename(columns={"user_id": "size"}).reset_index().drop(columns="size")

+---------+------------+
| user_id |  on_pm_at  |
+---------+------------+
|    2124 | 2018-06-30 |
|   18420 | 2018-02-28 |
+---------+------------+

它为我提供了每个用户的起点,但我不知道如何进行。我见过datetime.timedelta,但不能有几个月的变化。有什么办法可以达到我期望的数据帧?不必从我以前的尝试开始。

1 个答案:

答案 0 :(得分:2)

月周期解决方案:

首先将months的列to_period转换为Period的{​​{1}},然后将itertuplesperiod_range一起使用,最后用于日期时间to_timestamp

now

Datetime的解决方案

相似的方法,在一个月的最后一天转换为df['a'] = df['on_pm_at'].dt.to_period('m') now = pd.Period(pd.datetime.now().strftime('%Y-%m'),freq='m') print (now) 2018-07 df1 = pd.concat([pd.Series(r.user_id,pd.period_range(r.a, now, freq='m')) for r in df.itertuples()]).reset_index() df1.columns = ['months','user_id'] df1['months'] = df1['months'].dt.to_timestamp('m') print (df1) months user_id 0 2018-06-30 2124 1 2018-07-31 2124 2 2018-02-28 18420 3 2018-03-31 18420 4 2018-04-30 18420 5 2018-05-31 18420 6 2018-06-30 18420 7 2018-07-31 18420 ,然后转换为month period,并使用date_range

timestamp