pandas 用于datetime.date创建组的Bin www.example.com对象

y3bcpkx1  于 2022-11-27  发布在  其他
关注(0)|答案(2)|浏览(146)

我有一些数据,我想根据特定的时间点分为四组-时间点由特定的日期给出。
我拥有的数据如下(假设已经创建了df):

df["date"] = pd.to_datetime(df["date"], format = "%Y-%m-%d")
df["year"] = df["date"].dt.year
df["month"] = df["date"].dt.month

df.groupby(by = "year", as_index = False).agg({"month":pd.Series.nunique})

| 年份|月份|
| - -| - -|
| 二〇一五年|三个|
| 二〇一六年|十二|
| 二〇一七年|十二|
| 二〇一八年|十二|
| 二〇一九年|十二|
| 小行星2020|十二|
| 小行星2021|十二|
| 小行星2022|九个|
请注意,在此数据中,2015年和2022年不是完整年份。
我的想法是,因为我总共有84个月的数据(3 + (6*12) + 9 = 84),所以我可以将数据分成四组,这样每组大约有21个月的数据84 / 4 = 21
为此,我首先从数据集中最早的日期2015-10-02开始,然后加上21个月:

from dateutil.relativedelta import relativedelta

min_date = df["date"].min().date()
print([min_date, min_date + relativedelta(months = 21)]

#output
[datetime.date(2015, 10, 2), datetime.date(2017, 7, 2)]

此日期范围将构成第一组将落入的第一个 * bin *
第二组将落入一个日期范围,其中最小日期将比前一组日期范围的最大日期多 * 一天 *:

"2017-07-02" + relativedelta(days = 1) = "2017-07-03"

这将确保不同组的仓不重叠。
最后一个组中的数据会少一些,因为它将包括整个数据集中截至最新日期的数据,即2022-09-30
总的来说,不同组的日期范围框如下所示
| 分组|日期范围|
| - -| - -|
| A级|"2015年10月2日"、"2017年7月2日"|
| 乙|"2017年7月3日"、"2019年4月3日"|
| C语言|"2019年4月4日"、"2021年1月4日"|
| D级|"2021年1月5日"、"2022年9月30日"|
我知道我可以手动找到这些日期范围,并使用它们来过滤数据集,以生成np.select的组,但这不是很有效。

df["Group"] = np.select(
    condlist = [
        (df["date"] >= "2015-10-02") & (df["date"] <= "2017-07-02"),
        (df["date"] >= "2017-07-03") & (df["date"] <= "2019-04-03"),
        (df["date"] >= "2019-04-04") & (df["date"] <= "2021-01-04"),
        (df["date"] >= "2021-01-05") & (df["date"] <= "2022-09-30")
    ],
    choicelist = ["A", "B", "C", "D"]
)

当然,一定有一种方法可以找到这些值(以我想要的方式),而不必手动找到它们

j5fpnvbx

j5fpnvbx1#

您可能想看看pd.cut

# toy data
df = pd.DataFrame(pd.date_range('2020-01-01', '2022-01-01'), columns = ['date'])

          date
0   2020-01-01
1   2020-01-02
2   2020-01-03
3   2020-01-04
4   2020-01-05
..         ...

您可以生成存储箱的标签和边界。

from numpy import datetime64
bin_labels = [1, 2, 3, 4]
cut_bins = [datetime64('2019-12-31'), datetime64('2020-04-01'), datetime64('2020-12-31'), datetime64('2021-09-01'), datetime64('2022-01-01')]

并将回收箱保存到新列中。

df['cut'] = pd.cut(df['date'], bins = cut_bins, labels = bin_labels]

          date cut
0   2020-01-01   1
1   2020-01-02   1
2   2020-01-03   1
3   2020-01-04   1
4   2020-01-05   1
..         ...  ..
727 2021-12-28   4
728 2021-12-29   4
729 2021-12-30   4
730 2021-12-31   4
731 2022-01-01   4

希望能有所帮助。

bn31dyow

bn31dyow2#

我已经找到了一种我认为有效的方法(对于那些将来可能对日期-时间值分组感兴趣的人)-假设数据与问题描述中给出的数据相同:

from dateutil.relativedelta import relativedelta
import numpy as np

dates = []
start = df["date"].min().date()
dates.append(np.datetime64(start))
while start <= df["date"].max().date():
    start = start + relativedetla(months = 21)
    dates.append(np.datetime64(start))

df["Group"] = pd.cut(
    df["date"], bins = dates,
    labels = ["A", "B", "C", "D"],
    right = False #right = False ensures no group overlap in date values
)

相关问题