【问题标题】:How to sort CSV file in python by time interval如何按时间间隔在python中对CSV文件进行排序
【发布时间】:2020-02-22 17:20:12
【问题描述】:

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

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

所以我需要按时间对列表进行排序并将其分组到会话中。如果时差不大于 30 分钟,则视为 1 个会话。如果超过 30 分钟,则视为新会话。

所以用户 2222 只在 1 个会话中 用户 5555555 将处于 3 个不同的会话中,因为 item_id 0,2 和 1 是在不同的日期创建的。

=====================================
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
... ... ... ... ...

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

另一个问题是我以某种方式将列的名称从 uuid,created_at,item_id 更改为 1, 2,3,正如您在结果中看到的那样。

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

预期的结果应该是

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 个用户每天有多少会话,或者考虑到我们在一个会话中有 2 个或更多项目,会话持续多长时间。

【问题讨论】:

    标签: python python-3.x pandas csv


    【解决方案1】:

    这是一个必不可少的孤岛和间隙问题。对于每个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()获取累计和,其作用是将每一行分配到对应的岛。

    【讨论】:

      猜你喜欢
      • 2021-07-21
      • 2013-06-18
      • 2018-04-14
      • 2018-05-24
      • 2021-07-21
      • 1970-01-01
      • 2015-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多