【问题标题】:Optimise Code to improve performance and reduce Execution time优化代码以提高性能并减少执行时间
【发布时间】:2022-01-03 14:37:26
【问题描述】:

我有一个完美运行的代码。但是,当我运行一个大的 CSV 文件(大约 2GB)时,代码的完整执行大约需要 15-20 分钟。有没有一种方法可以优化下面的代码以减少执行时间从而提高性能?

from csv import reader, writer
import pandas as pd

path = (r"data.csv")

data = pd.read_csv(path, header=None)

last_column = data.iloc[: , -1]

arr = [i+1 for i in range(len(last_column)-1) if (last_column[i] == 1 and last_column[i+1] == 0)]

ch_0_6 = []
ch_7_14 = []
ch_16_22 = []

with open(path, 'r') as read_obj:
    csv_reader = reader(read_obj)
    rows = list(csv_reader)

for j in arr:
    
    # Channel 1-7
    ch_0_6_init = [int(rows[j][k]) for k in range(1,8)]
    bin_num = ''.join([str(x) for x in ch_0_6_init])
    dec_num = int(f'{bin_num}', 2)
    ch_0_6.append(dec_num)
    ch_0_6_init = []

    # Channel 8-15
    ch_7_14_init = [int(rows[j][k]) for k in range(8,16)]
    bin_num = ''.join([str(x) for x in ch_7_14_init])
    dec_num = int(f'{bin_num}', 2)
    ch_7_14.append(dec_num)
    ch_7_14_init = []

    # Channel 16-22
    ch_16_22_init = [int(rows[j][k]) for k in range(16,23)]
    bin_num = ''.join([str(x) for x in ch_16_22_init])
    dec_num = int(f'{bin_num}', 2)
    ch_16_22.append(dec_num)
    ch_16_22_init = []

样本数据:

0.0114,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,0,0,1
0.0112,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,1,0,0,0,0
0.0115,0,1,0,1,1,1,0,1,0,0,1,0,0,0,1,1,1,0,1,0,0,0,1
0.0117,0,1,0,1,1,1,0,1,0,0,1,0,0,0,1,1,1,0,1,0,0,0,0
0.0118,0,1,0,0,1,1,0,0,0,1,0,1,0,0,1,1,1,0,1,0,0,0,1

根据所选择的通道,将二进制数字连接起来形成一个十进制数。

【问题讨论】:

  • 您能否添加几行示例数据进行测试,并添加简短说明您想要实现的目标
  • @MartinEvans 我已经编辑了这个问题。谢谢!
  • 一方面,您应该想办法避免加载整个巨大的 csv 文件两次。您正在使用 pandas 和标准 csv 阅读器阅读它!
  • @JaredSmith 感谢您的建议。哪个是更好的 pandas 或标准 csv 阅读器以减少执行时间?
  • @Pressing_Keys_24_7 IDK 但我敢打赌,两者之间的差异将完全相形见绌(尤其是对于那么大的文件,你在说关于可能一次读取 4GB!! 到内存中,大概是在用户设备上)。使用使处理数据更清晰/更容易的任何一种,如果仍然太慢,请然后担心哪个更快。

标签: python csv


【解决方案1】:

仅使用 csv 模块,您可以尝试以下类型方法:

from csv import reader, writer

ch_0_6 = []
ch_7_14 = []
ch_16_22 = []

with open('data.csv', 'r') as f_input:
    csv_input = reader(f_input)
    last_row = ['0']

    for row in csv_input:
        if last_row[-1] == '1' and row[-1] == '0':
            ch_0_6.append(int(''.join(row[1:8]), 2))
            ch_7_14.append(int(''.join(row[8:16]), 2))
            ch_16_22.append(int(''.join(row[16:23]), 2))
            
        last_row = row
    
print(ch_0_6)
print(ch_7_14)
print(ch_16_22)

对于您的示例数据,这将显示:

[32, 46]
[1, 145]
[104, 104]

如前所述,您最初的方法是将整个文件两次读入内存。第一遍只是确定要解析哪些行。这可以在读取时通过跟踪循环中的前一行来完成。仅此一项就应该会显着加快速度。

从二进制列表元素到十进制元素的转换也效率更高一些。

这种方法也适用于更大的文件。

【讨论】:

  • 感谢您的帮助!
猜你喜欢
  • 2019-12-14
  • 1970-01-01
  • 2021-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-04
  • 2012-11-09
相关资源
最近更新 更多