【问题标题】:Is there a Pandas way to group dates that are less than 2 minutes apart in a dataframe?有没有一种 Pandas 方法可以对数据框中相隔不到 2 分钟的日期进行分组?
【发布时间】:2021-05-03 08:20:56
【问题描述】:

我想对我的数据进行分组,以将接近的日期放在一起。 (不到 2 分钟)

这是我得到的一个例子

> datas = [['A', 51, 'id1', '2020-05-27 05:50:43.346'], ['A', 51, 'id2',
> '2020-05-27 05:51:08.347'], ['B', 45, 'id3', '2020-05-24
> 17:23:55.142'],['B', 45, 'id4', '2020-05-24 17:23:30.141'], ['C', 34,
> 'id5', '2020-05-23 17:31:10.341']]
> 
> df = pd.DataFrame(datas, columns = ['col1', 'col2', 'cold_id',
> 'dates'])

前 2 行有结束日期,第 3 行和第 4 行相同,第 5 行单独。

我想得到这样的东西:

> datas = [['A', 51, 'id1 id2', 'date_1'], ['B', 45, 'id3 id4',
> 'date_2'], ['C', 34, 'id5', 'date_3']]
> 
> df = pd.DataFrame(datas, columns = ['col1', 'col2', 'col_id',
> 'dates'])

以pythonic方式制作并不难,但我必须在大数据帧上制作,使用groupby方法的pandas方式会非常有效。

在我尝试的日期列上应用日期时间方法后:

> df.groupby([df['dates'].dt.date]).agg(','.join)

但是 .dt.date 方法每天而不是每 2 分钟给出一个日期。

你有解决办法吗?

谢谢

【问题讨论】:

  • 我可以在计算时间增量之前使用col1col2 成对分组,还是仅基于日期而不管其他列的值如何?事实上,(A,51) 有没有可能出现两次以上?如果2分钟间隔内有3个或更多dates

标签: python-3.x pandas pandas-groupby


【解决方案1】:

查看输出似乎我们正在尝试将dates by 2 min freqcol1, col2 分组。

代码

df['dates'] = pd.to_datetime(df.dates)
df.groupby([pd.Grouper(key='dates', freq='2 min'), 
            'col1', 'col2']).agg(','.join).reset_index().sort_values('col1').reset_index(drop=True)

输出

    dates             col1  col2    cold_id
0   2020-05-27 05:50:00 A   51      id1,id2
1   2020-05-24 17:22:00 B   45      id3,id4
2   2020-05-23 17:30:00 C   34      id5

【讨论】:

  • 这正是我需要的,谢谢,我应该看看pd.Grouper
【解决方案2】:

仅使用日期,这就是我对您的行进行分类的方法:

首先,将日期转换为时间戳以便轻松比较:

from datetime import datetime
import time

df["dates"] = df["dates"].apply(lambda x : int(time.mktime(datetime.strptime(x,"%Y-%m-%d %H:%M:%S.%f").timetuple())))

然后,按日期对它们进行排序:

df = df.sort_values("dates")

最后,使用这个answer,我创建了一个列group 来确定结束日期。如果日期足够接近(在我们的示例中为 120 秒),则第一行将 1 添加到组列中。第二行将填充列组以删除 NaN 并分配组:

df.loc[(df.dates.shift() < df.dates - 120),"group"] = 1
df['group'] = df['group'].cumsum().ffill().fillna(0)

这给了我:

  col1  col2 cold_id       dates  group
4    C    34     id5  1590247870   0.00
3    B    45     id4  1590333810   1.00
2    B    45     id3  1590333835   1.00
0    A    51     id1  1590551443   2.00
1    A    51     id2  1590551468   2.00

现在,要连接您的cold_id,您可以按组分组并使用transform 加入每个组的cold_id

df["cold_id"] = df.groupby(["group"],as_index=False)["cold_id"].transform(lambda x: ','.join(x))
df = df.drop_duplicates(subset=["cold_id"])

这终于给了你这个数据框:

  col1  col2  cold_id       dates  group
4    C    34      id5  1590247870   0.00
3    B    45  id4,id3  1590333810   1.00
0    A    51  id1,id2  1590551443   2.00

【讨论】:

  • 感谢您的回复,我意识到我距离如何使用pandas还有很长的路要走。
猜你喜欢
  • 2015-08-27
  • 1970-01-01
  • 2015-01-02
  • 1970-01-01
  • 1970-01-01
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多