【问题标题】:comparing two large csv files takes too long比较两个大的 csv 文件需要很长时间
【发布时间】:2021-05-09 15:47:04
【问题描述】:

我有两个大型 CSV 文件,其中包含要比较的数据。我使用了 pandas,因此我有两个数据框可以更轻松地使用,但是程序需要很长时间才能完成并比较所有数据。

我将发送的数据与接收的数据进行比较,以获得延迟时间,为此我放置了一个双循环并且程序运行良好。但我想知道是否有更快的方法来执行此操作,因为对于我最重的文件,完成程序需要几天时间。

我正在处理大文件,第一个有 68001 行,第二个有 837190 行。但是这个程序需要的时间太长了。提前致谢。

解释我的代码是如何工作的

我正在对 MQTT 代理进行一些性能测试,为此我创建了发送和接收消息的 paho 客户端,发送的数据存储在 csv 中,以便稍后计算延迟。发布者(发布的用户)的 csv 包含发布者的客户端 ID、帐户、时间戳和订阅的主题。

虽然订阅者(接收消息的用户)包含接收消息时的时间戳、接收到的消息、计数(消息数量的计数器)、发布者的客户端 ID 和主题。

现在要计算延迟,使用从 0 开始的循环逐行评估。这就是为什么我对 df1(发布者的数据帧)和 df2 的第一行(消息接收者的数据帧)使用循环。

使用条件“如果”,我比较客户端的 ID、计数以及从数据帧 df1 的第一行发送消息的主题,这对应于第一个发送消息的客户端,我比较它与dataframe df2的第一行,查看client ID、count和topic是否匹配。

如果一致,我继续减去时间来计算延迟,将自己定位在时间对应的列中,然后将它们存储在另一个csv中,这几乎是你能看到的最后一行。

如果条件不满足,则继续并进入与df2对应的循环的下一次迭代。因此 df1 将保持在同一位置,直到 df2 循环完成评估其数据帧的所有行中是否存在匹配项。我希望我已经很好地解释了自己。

    #/////////////////////////////////////////////////////////////////
    #!/usr/bin/env python
    # encoding: utf-8

    import pandas as pd
    import numpy as np
    import re
    import datetime as dt
    #from datetime import datetime
    #import matplotlib.pyplot as plt

    file1='/home/carmen/Desktop/Pruebas/QoS2/50-1/latency_users/publicadores4.csv'
    file2='/home/carmen/Desktop/Pruebas/QoS2/50-1/latency_users/suscriptor_hilos4.csv'

    Resultados='/home/carmen/Desktop/Resultados/QoS2/50-1/Latencia4.csv'
    f=open(Resultados,'w')
    f.write("Client,Count,Latency,Topic \n")
    f.close()

    #Almacena los datos a un archivo csv
    data1=pd.read_csv(file1)
    data2=pd.read_csv(file2)

    #Convierte los datos en frame
    df1=pd.DataFrame(data1)
    df2=pd.DataFrame(data2)

    #Mostrar informacion general del archivo
    data1.info()
    data2.info()

    pd.set_option('display.max_colwidth',1000)

    #Extrae de Timestamp solo la hora:min:segundos;microseg
    df1['Time1']=df1['Timestamp'].str.extract('(..:..:.........)',expand=True)
    df2['Time2']=df2['Timestamp'].str.extract('(..:..:.........)',expand=True)

    #Convierte la columna timestamp a formato fecha y/o hora
    df1['Time1']=pd.to_datetime(df1['Time1'])
    df2['Time2']=pd.to_datetime(df2['Time2'])


    with open(Resultados, "a") as f:
        for i in range(len(df1)):
            for j in range(len(df2)):
                if( (df1.loc[i,'Client']== df2.loc[j,'Cliente']) and (df1.loc[i,'Count']==df2.loc[j,'Count'])\
                 and (df1.loc[i,'Topic']==df2.loc[j,'Topic'])):

                    print(df1.loc[i,'Client'],df2.loc[j,'Cliente'],df1.loc[i,'Count'],df2.loc[j,'Count'],df1.loc[i,'Time1'],df1.loc[i,'Topic'],df2.loc[j,'Topic'])


                    df1.loc[i,'Latencia']=(df2.loc[j,'Time2']-df1.loc[i,'Time1']) #calculando la diferencia   
                    df1['Latencia'] = df1['Latencia'].astype(str).str.split('0 days ').str[-1] #delete 0days of the result
            
                    f.write(str(df2.loc[j,'Cliente'])+","+str(df2.loc[j,'Count'])+","+str(df1.loc[i,'Latencia'])+","+str(df1.loc[i,'Topic'])+","+str(df2.loc[j,'Topic'])+'\n')

                else:
                    continue

要比较的数据示例:

df1:

 Client,Count,Timestamp,Topic
    Client_0000,000000,2021-04-22 09:01:43.627250,topic/2
    Client_0001,000000,2021-04-22 09:01:43.628319,topic/2
    Client_0002,000000,2021-04-22 09:01:43.629341,topic/3
    Client_0003,000000,2021-04-22 09:01:43.630497,topic/2
    Client_0004,000000,2021-04-22 09:01:43.631836,topic/1
    Client_0005,000000,2021-04-22 09:01:43.633540,topic/3
    Client_0006,000000,2021-04-22 09:01:43.635005,topic/2
    CONTINUE....

df2:

Timestamp,Message,Count,Cliente,Topic
    2021-04-22 09:01:43.639642,¡Hello World! ¡Welcome! The temperature is:91 °C,000000,Client_0000,topic/2
    2021-04-22 09:01:43.642274,¡Hello World! ¡Welcome! The temperature is:91 °C,000000,Client_0000,topic/2
    2021-04-22 09:01:43.641392,¡Hello World! ¡Welcome! The temperature is:91 °C,000000,Client_0000,topic/2
    2021-04-22 09:01:43.643774,¡Hello World! ¡Welcome! The temperature is:91 °C,000000,Client_0000,topic/2
    2021-04-22 09:01:43.637687,¡Hello World! ¡Welcome! The temperature is:91 °C,000000,Client_0000,topic/2
    2021-04-22 09:01:43.639910,¡Hello World! ¡Welcome! The temperature is:91 °C,000000,Client_0000,topic/2
    2021-04-22 09:01:43.643982,¡Hello World! ¡Welcome! The temperature is:91 °C,000000,Client_0000,topic/2
    2021-04-22 09:01:43.653039,¡Hello World! ¡Welcome! The temperature is:91 °C,000000,Client_0000,topic/2
    2021-04-22 09:01:43.659924,¡Hello World! ¡Welcome! The temperature is:91 °C,000000,Client_0000,topic/2

【问题讨论】:

    标签: python pandas dataframe csv


    【解决方案1】:

    您可以使用合并: 它应该比运行循环更快

    df2 = df2.rename(columns={'Cliente': 'Client'})
    df = df1.merge(df2, 'inner', on=['Client', 'Topic', 'Count'])
    df['latency'] = df['Timestamp_y'] - df['Timestamp_x']
    

    请注意,我已将 Cliente 从 df2 重命名为 Client,如果需要,您可以稍后在合并后将其更改回来。

    或者您也可以使用left_onright_on

    df = df1.merge(df2, 'inner', left_on=['Client', 'Topic', 'Count'], right_on=['Cliente', 'Topic', 'Count'])
    df['latency'] = df['Timestamp_y'] - df['Timestamp_x']
    

    这是假设您的时间戳采用有效格式,您可以减去它们以获得延迟。以下是输出 df 的示例:

        Client          Count           Timestamp_x          Topic          Timestamp_y            Message   Cliente          latency
    0   Client_0000     000005  2021-05-09 13:05:36.316499  topic/2     2021-05-09 13:05:36.353677  Hello   Client_0000     0 days 00:00:00.037178
    1   Client_0063     000005  2021-05-09 13:05:39.505920  topic/6     2021-05-09 13:05:39.532888  Hello   Client_0063     0 days 00:00:00.026968
    2   Client_0071     000008  2021-05-09 13:05:39.913016  topic/5     2021-05-09 13:05:39.931340  Hello   Client_0071     0 days 00:00:00.018324
    3   Client_0082     000009  2021-05-09 13:05:40.487390  topic/9     2021-05-09 13:05:40.521418  Hello   Client_0082     0 days 00:00:00.034028
    4   Client_0097     000006  2021-05-09 13:05:41.248995  topic/10    2021-05-09 13:05:41.264659  Hello   Client_0097     0 days 00:00:00.015664
    
    

    【讨论】:

    • 非常感谢!!这正是我所需要的,我什至不知道 Dataframe 函数及其有用性,执行时间只有几秒钟,不像循环需要几天。再次感谢您
    猜你喜欢
    • 2022-06-20
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多