python - 如何在python中按时间间隔对CSV文件进行排序

标签 python python-3.x pandas csv

我想根据 CSV 文件中特定项目之间的时间差(30 分钟的差异)将 CSV 文件分组为集群。

然后我想使用排序后的数据进行绘图,因此我需要对 CSV 文件进行排序,以便我能够使用新数据调用图表上的 x 和 y 轴。

所以我需要的是按时间对这个列表进行排序并将其分组为 session 。如果时间差不大于30分钟,则考虑一场。如果超过 30 分钟,则被视为新 session 。

因此用户 2222 仅在 1 个 session 中 由于 item_id 0,2 和 1 是在不同日期创建的,因此用户 5555555 将处于 3 个不同的 session 中。

=====================================
Sample dataset in CSV: 
=====================================

uuid,created_at,item_id
2222,2017-01-16 10:54:43.386,0
2222,2017-01-16 10:56:25.717,1
2222,2017-01-16 10:55:50.642,2
5555555,2017-01-16 10:54:19.796,3
5555555,2017-01-16 10:55:10.654,1
5555555,2017-01-17 10:54:55.643,2
5555555,2017-01-27 10:56:02.860,0
323232,2017-01-25 10:56:16.432,3

=====================================
                MY CODE
=====================================
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def sessions(filename):

    data = pd.read_csv(filename, parse_dates=[1])

    data_sort= data.sort_values(by=['uuid', 'created_at'])

    cluster = (data_sort["created_at"].diff() > pd.Timedelta(minutes=30))

    data_sort.groupby(cluster)
#print(data_sort.to_string())
    print()

    #print(cluster)

    #data_sort['c']=cluster

    #print(data_sort.to_string())

    a=data_sort.groupby(['uuid'])



    sessions=[]



    for name, group in data_sort.groupby('uuid'):

        session=group.groupby(group["created_at"].diff()>pd.Timedelta(minutes=30))

        for n,g in session:

            sl=g.values.tolist()

            sessiondict=dict()

            sessiondict['start']=sl[0][1]

            sessiondict['end']=sl[-1][1]

            sessiondict['uuid']=sl[0][0]

            sessiondict['count']=len(sl)

            sessions.append([sessiondict['uuid'],

                             sessiondict['start'],

                             sessiondict['end'],

                             sessiondict['count']])





    return pd.DataFrame(sessions)


========================================
              RESULT 
=======================================
0   1                2                                  3
0   2222    2016-12-25 11:27:22.905 2017-02-01 21:34:10.479 3
1   2222    2016-12-28 09:40:57.271 2017-02-01 21:29:22.404 1
2   5555555 2017-01-05 15:03:52.859 2017-01-16 19:04:01.355 4
3   5555555 2017-01-09 18:45:52.102 2017-01-16 18:30:06.578 2
4   323232 2016-12-12 20:49:47.972  2016-12-12 20:54:34.990 1
... ... ... ... ...

我遇到的问题如下:代码没有考虑第一个 session 。因此,对于用户 5555555,我总共应该有 3 个 session 。 16日1次,17日2次,27日3次。

另一个问题是,我以某种方式将列的名称从 uuid,created_at,item_id 更改为 1, 2,3,如结果中所示。

所以我想更改以下代码,以便每个 session 都有自己的日期。

预期结果应该是

uuid created_at session_id

5555555 2017-01-16 10:54:19 one session id
5555555,2017-01-16 10:55:10

5555555 2017-01-17 10:54:55 2nd session id

5555555 2017-01-25  3rd session id

这样我就可以知道 1 个用户每天有多少个 session ,或者考虑到我们在一个 session 中有 2 个或更多项目, session 持续多长时间。

最佳答案

这本质上是一个岛屿和缺口问题。对于每个 uuid ,如果一行与其前一行之间的时间间隔大于 30 分钟。我们开始一个新的岛屿。

试试这个:

def summarize(group):
    return group.assign(
        session_id=group['created_at'].diff().div(pd.Timedelta(minutes=1)).gt(30).cumsum()
    )

df.sort_values(['uuid', 'created_at']) \
    .groupby('uuid').apply(summarize) \
    .reset_index(drop=True)

结果:

      uuid              created_at  item_id  session_id
0     2222 2017-01-16 10:54:43.386        0           0
1     2222 2017-01-16 10:55:50.642        2           0
2     2222 2017-01-16 10:56:25.717        1           0
3   323232 2017-01-25 10:56:16.432        3           0
4  5555555 2017-01-16 10:54:19.796        3           0
5  5555555 2017-01-16 10:55:10.654        1           0
6  5555555 2017-01-17 10:54:55.643        2           1
7  5555555 2017-01-27 10:56:02.860        0           2
<小时/>

其工作原理如下:

  • diff()计算当前行与上一行之间的差异,结果是 Timedelta对象
  • div(...)转换Timedelta将对象转换为十进制分钟(即 10.6 分钟)
  • gt(30)检查时间间隔是否大于 30 分钟。如果是,则返回True <=> 1 ,这会开始一个新的岛屿。
  • cumsum()获取累积和,其作用是将每一行分配给相应的岛屿。

关于python - 如何在python中按时间间隔对CSV文件进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58574040/

相关文章:

python - PySpark:如何根据其他行值的值更改行+列的值

python - 访问具有多个层次结构的 JSON 文件

python-3.x - 创建一个绘制线图,其中线按类别着色?

python - 我不应该能够填充通过变换导出的列吗?

python - 索引在 Pandas 中是如何工作的?

python - 如何从 tkinter OptionMenu 获取列表变量?

python - 当 N 大于组数时 nlargest(N) 的行为?

python - 如何为Celery beat动态添加定时任务

python - 将空行转换为 Pandas 中的列

python - 如何在 pandas 数据框中指定列类型