使用python计算文件中条目之间的时间差

使用python计算文件中条目之间的时间差,python,python-2.7,csv,python-3.x,Python,Python 2.7,Csv,Python 3.x,我有一个csv文件,数据格式如下 日期、时间、事件、用户、网络。 我需要遍历这个文件的每一行,如果event==start, 继续,直到到达同一用户和网络的event==end行, 然后计算两个事件之间的时间差。 我有以下代码: import csv import datetime import time with open('dates.csv', 'rb') as csv_file: csv_read = csv.reader(csv_file) for row in cs

我有一个csv文件,数据格式如下
日期、时间、事件、用户、网络
。 我需要遍历这个文件的每一行,如果event==start, 继续,直到到达同一用户和网络的event==end行, 然后计算两个事件之间的时间差。 我有以下代码:

import csv
import datetime
import time

with open('dates.csv', 'rb') as csv_file:
    csv_read = csv.reader(csv_file)
    for row in csv_read:
        if row[2]=="start":
            n1=datetime.datetime.strptime(row[1], '%H:%M:%S')

            for row2 in csv_read:
                if (row2[2]=="End" and row[3]==row2[3] and row[4]==row2[4]):
                    n2=datetime.datetime.strptime(row2[1], '%H:%M:%S')

                    print row[2],row[1], row2[2], row2[1]

                    diff = n2 - n1
                    print "time difference = ", diff.seconds
                    break
但这段代码的问题是,当它找到匹配项“End”并计算时间时,它将从匹配项“End”后面的行开始搜索,忽略它前面的行。 例如

May,20,9:02:22,2010,start,user1,net-3
May,20,9:02:23,2010,start,user1,net-3
May,20,9:02:55,2010,start,user1,net-2
May,20,9:02:55,2010,End,user1,net-3
May,20,9:03:43,2010,End,user1,net-2
May,20,9:02:55,2010,End,user1,net-3
May,20,9:03:43,2010,End,user1,net-2
May,20,9:03:44,2010,start,user1,net-2
May,20,9:03:49,2010,End,user1,net-2
将仅产生以下输出:

Connect 9:02:22 Disconnect 9:02:55
time difference =  33
Connect 9:03:44 Disconnect 9:03:49
time difference =  5
请问,有人知道如何解决这个问题吗? 是否可以将时差作为额外列添加到现有数据中

谢谢

我已经更新了代码,但现在我面临一个新的问题,我的文件包含35734行,但输出文件只包含350行,我不明白为什么会发生这种情况,我将感谢您的帮助,谢谢 更新代码:

l1=[]  ## empty list
l2=[]  ## empty list

csv_file=open('dates_read.csv', 'r+')
csv_wfile=open('dates_write.csv', 'w+')

csv_read = csv.reader(csv_file)
csv_read1 = csv_read
csv_write = csv.writer(csv_wfile)
for row in csv_read:
    s=csv_read.line_num
    if (row[4]=="start" and (s not in l1)):
        n1=datetime.datetime.strptime(row[2], '%H:%M:%S')

        l1.append(s)
        month = str(row[0])
        day = int(row[1])
        time = str(row[2])
        year = int(row[3])
        user = str(row[5])
        net = str(row[6])
        dwell_time = str(row[7])
        for row2 in csv_read1:
            e=csv_read1.line_num
            if (row2[4]=="End" and row[5]==row2[5] and row[6]==row2[6] and (csv_read1.line_num not in l2)and s<e):
                n2=datetime.datetime.strptime(row2[2], '%H:%M:%S')
                diff = n2 - n1
                dwell_time= diff
                print("time difference = ", diff.seconds,"\n")
                csv_write.writerow([month, day, time, year, user, net, dwell_time])
                l2.append(e)
                break
print (s) #prints 818
print (e) #prints 35734 
l1=[]##空列表
l2=[]##空列表
csv_file=open('dates_read.csv','r+'))
csv\u wfile=open('dates\u write.csv','w+'))
csv\u read=csv.reader(csv\u文件)
csv\u read1=csv\u read
csv\u write=csv.writer(csv\u wfile)
对于csv_中的行,请阅读:
s=csv\u read.line\u num
如果(第[4]行)=“开始”和(不在l1中):
n1=datetime.datetime.StrTime(第[2]行,'%H:%M:%S')
l1.追加
月份=str(第[0]行)
日期=整数(第[1]行)
时间=str(第[2]行)
年份=整数(第[3]行)
user=str(第[5]行)
net=str(第[6]行)
停留时间=str(第[7]行)
对于csv_read1中的第2行:
e=csv\u read1.line\u num

如果(row2[4]=“End”和row[5]=“row2[5]和row[6]=“row2[6]和(csv_read1.line_num不在l2中)和s我认为最好使用一个映射来解决这个问题

将(用户id、网络id)定义为键,将(启动状态、启动时间)定义为值,如下所示:

class UserNet:
   user_id = -1
   net_id = -1
   // Other Operation

class StartStatus:
   start_flag = False
   start_time = -1
   // Other Operation
当您读取一行时,该行中的第一个判断状态字符串是开始或结束

如果结束了,那么使用 从那一行读,找到新的地图结构,找到开始时间和负号,得到你的答案

如果是“开始”,则将该值插入新的贴图结构中


如果您不希望错误判断,那么启动标志是不必要的,它代表相同的重复启动标志,也许您不需要它。

我认为最好使用地图解决此问题

将(用户id、网络id)定义为键,将(启动状态、启动时间)定义为值,如下所示:

class UserNet:
   user_id = -1
   net_id = -1
   // Other Operation

class StartStatus:
   start_flag = False
   start_time = -1
   // Other Operation
当您读取一行时,该行中的第一个判断状态字符串是开始或结束

如果结束了,那么使用 从那一行读,找到新的地图结构,找到开始时间和负号,得到你的答案

如果是“开始”,则将该值插入新的贴图结构中


如果您不希望错误判断,那么start\u标志是不必要的,它代表相同的重复开始,也许您不需要它。

代码的唯一问题是,在遇到第一个start关键字之后,您正在遍历END关键字的行。相反,它应该遍历lin从一开始就是文件的一部分。 因此,我们还必须考虑到同一行不会再次被遍历。为此,我们可以使用一个列表,它可以保存被遍历行的行号

我没有编写新代码,只对代码进行了更改

>>> l=[]  ## empty list
>>> csv_file=open('dates.csv')
>>> csv_read = csv.reader(csv_file)
>>> for row in csv_read:
            if row[0].split()[4]=="start":
                n1=datetime.datetime.strptime(row[0].split()[2], '%H:%M:%S')
                s=csv_read.line_num
                csv_file1=open('/Python34/Workspace/Stoverflow/dates.csv')
                csv_read1 = csv.reader(csv_file1)
                for row2 in csv_read1:
                    e=csv_read1.line_num
                    ## Inside if iam adding to more checks that verify that the same line is not traversed again and the END flag is always encountered after START flag
                    if (row2[0].split()[4]=="End" and row[0].split()[6]==row2[0].split()[6] and row[0].split()[5]==row2[0].split()[5] and (csv_read1.line_num not in l) and s<csv_read1.line_num):
                        n2=datetime.datetime.strptime(row2[0].split()[2], '%H:%M:%S')
                        print("Connect : ",row[0].split()[2]," Disconnect :",row2[0].split()[2])
                        diff = n2 - n1
                        print("time difference = ", diff.seconds,"\n")
                        l.append(csv_read1.line_num)
                        del csv_read1
                    break
            del csv_file1
>>l=[]##空列表
>>>csv\u文件=打开('dates.csv'))
>>>csv\u read=csv.reader(csv\u文件)
>>>对于csv_中的行,请阅读:
如果行[0]。拆分()[4]=“开始”:
n1=datetime.datetime.StrTime(行[0].split()[2],“%H:%M:%S”)
s=csv\u read.line\u num
csv_file1=open(“/Python34/Workspace/Stoverflow/dates.csv”)
csv_read1=csv.reader(csv_file1)
对于csv_read1中的第2行:
e=csv\u read1.line\u num
##在内部,如果iam添加到更多检查,以验证同一行不会再次遍历,并且在开始标志之后始终会遇到结束标志

如果(第2行[0]。拆分()[4]==“结束”和第[0]行。拆分()[6]==第2行[0]。拆分()[6]和第[0]行。拆分()[5]==第2行[0]。拆分()[5]和(csv_read1.line_num不在l中)代码的唯一问题是,在遇到第一个START关键字之后,您正在遍历END关键字的行。相反,它应该从一开始就遍历文件的行。 因此,我们还必须考虑到同一行不会再次被遍历。为此,我们可以使用一个列表,它可以保存被遍历行的行号

我没有编写新代码,只对代码进行了更改

>>> l=[]  ## empty list
>>> csv_file=open('dates.csv')
>>> csv_read = csv.reader(csv_file)
>>> for row in csv_read:
            if row[0].split()[4]=="start":
                n1=datetime.datetime.strptime(row[0].split()[2], '%H:%M:%S')
                s=csv_read.line_num
                csv_file1=open('/Python34/Workspace/Stoverflow/dates.csv')
                csv_read1 = csv.reader(csv_file1)
                for row2 in csv_read1:
                    e=csv_read1.line_num
                    ## Inside if iam adding to more checks that verify that the same line is not traversed again and the END flag is always encountered after START flag
                    if (row2[0].split()[4]=="End" and row[0].split()[6]==row2[0].split()[6] and row[0].split()[5]==row2[0].split()[5] and (csv_read1.line_num not in l) and s<csv_read1.line_num):
                        n2=datetime.datetime.strptime(row2[0].split()[2], '%H:%M:%S')
                        print("Connect : ",row[0].split()[2]," Disconnect :",row2[0].split()[2])
                        diff = n2 - n1
                        print("time difference = ", diff.seconds,"\n")
                        l.append(csv_read1.line_num)
                        del csv_read1
                    break
            del csv_file1
>>l=[]##空列表
>>>csv\u文件=打开('dates.csv'))
>>>csv\u read=csv.reader(csv\u文件)
>>>对于csv_中的行,请阅读:
如果行[0]。拆分()[4]=“开始”:
n1=datetime.datetime.StrTime(行[0].split()[2],“%H:%M:%S”)
s=csv\u read.line\u num
csv_file1=open(“/Python34/Workspace/Stoverflow/dates.csv”)
csv_read1=csv.reader(csv_file1)
对于csv_read1中的第2行:
e=csv\u read1.line\u num
##在内部,如果iam添加到更多检查,以验证同一行不会再次遍历,并且在开始标志之后始终会遇到结束标志

如果(第2行[0].split()[4]==“End”和第[0]行。split()[6]==第2行[0].split()[6]和第[0]行。split()[5]==第2行[0].split()[5]和(csv_read1.line_num不在l中)和sHi,谢谢您的回答,但代码似乎不起作用,首先是在我使用第[0]行时。split()[
,但在我使用jst row[]
它工作了,但没有输出,在添加一些print语句后,第2行
中的if语句似乎没有执行S:2e:1s:3e:1s:4e:1s:7e:1
我将您的数据文件复制到一个txt文件中,后来我将其修改为.cs