【问题标题】:How to append python list to a numpy matrix in fastest way?如何以最快的方式将 python 列表附加到 numpy 矩阵?
【发布时间】:2021-12-17 02:54:22
【问题描述】:

我正在编写一个代码来读取多达十亿行的研究数据。我必须逐行读取数据,因为数据有多个块。每个块都有与其他块头和数据集不同的头。 我希望将这些数据集读入 Numpy 矩阵,以便执行矩阵运算。以下是基本代码。

    with open(datafile, "r") as dump:
        i = 0           # block line number
        line_no = 0     # total line number
        block_size = 0
        block_count = 0
        for line in dump:
            values = line.rstrip().rsplit()
            i += 1
            line_no += 1
            if i <= self.head_line_no:
                print(line)  # for test
                if self.tag_block in line or i == 1:      # 1st line of a block
                    # save block size after reading 1st block
                    if block_size == 0 and block_count == 0:
                        block_size = line_no - 1
                        i = 1               # reset block line number
                        self.box = []       # reset box constant
                        print(self.matrix)
                        self.matrix = np.zeros((0, 0), dtype="float")   # reset matrix

                    block_count += 1
                elif i == 2:
                    self.timestamp.append(values[0])
                elif i == 3 or i == 5:
                    continue
                elif i == 4:
                    if self.atom_no != 0 and self.atom_no != values[0]:
                        self.warning_message = "atom number in timestep " + self.timestamp[-1] + "is inconsistent with" + self.timestamp[-2]
                        config.ConfigureUserEnv.log(self.warning_message)
                    else:
                        pass
                    self.atom_no = values[0]
                elif i == 6 or i == 7 or i == 8:
                    self.box.append(values[0])
                    self.box.append(values[1])
                elif i == self.head_line_no:
                    values = line.rstrip().rsplit(":")
                    for j in range(1,len(values)):
                        self.column_name.append(values[j])
            else:
                if self.matrix.size != 0:
                    np_array = np.array(values)
                    self.matrix = np.append(self.matrix, np.array(np.asarray(values)), 0)     
                else:
                    np_array = np.array(values)
                    self.matrix = np.zeros((1,len(values)), dtype="float")
                    self.matrix = np.asarray(values)
        dump.close()
        print(self.matrix)       # for test
        print(self.matrix.size)  # for test

原始数据如下:

ITEM: TIMESTEP
100
ITEM: NUMBER OF ATOMS
17587
ITEM: BOX BOUNDS pp pp pp
0.0000000000000000e+00 4.3491000000000000e+01
0.0000000000000000e+00 4.3491000000000000e+01
0.0000000000000000e+00 1.2994000000000000e+02
ITEM: ATOMS id type q xs ys zs 
59 1 1.80278 0.110598 0.129682 0.0359397 
297 1 1.14132 0.139569 0.0496654 0.00692627 
315 1 1.17041 0.0832356 0.00620818 0.00507927 
509 1 1.67165 0.0420777 0.113817 0.0313991 
590 1 1.65209 0.114966 0.0630015 0.0447129 
731 1 1.65143 0.0501253 0.13658 0.0108512 
1333 2 1.049 0.00850751 0.0526546 0.0406341 
...... 

我希望添加如下矩阵数据:

matrix = [[59 1 1.80278 0.110598 0.129682 0.0359397],
[297 1 1.14132 0.139569 0.0496654 0.00692627],
[315 1 1.17041 0.0832356 0.00620818 0.00507927],
...]

如上所述,数据集的规模非常大。我希望使用最快的方式将数组追加到矩阵中。任何进一步的帮助和建议将不胜感激。

【问题讨论】:

    标签: python numpy performance


    【解决方案1】:

    以下是加快计算速度的一些要点:

    • 不要在循环中使用self.matrix = np.append(self.matrix, ...),这样做效率不高,因为它会为每次迭代重新创建一个新的增长数组(并复制旧数组)。这导致二次运行时间。使用纯 Python 列表代替 append 并将列表最终转换为 Numpy 数组。这是性能方面最关键的一点
    • 使用 self.box.extend((values[0], values[1])) 应该比执行两个 append 快​​得多。
    • 使用dtype="float"不是很清楚效率不是很高,请考虑使用dtype=np.float64代替(不需要Numpy解析)。
    • 使用 enumerate 可能比在循环中手动递增快一点。
    • Cython 可以帮助你加速这个程序,如果这对你的输入文件来说不够快的话。应该记住,与使用 C 或 C++ 等语言编写的已编译本机程序/模块相比,标准 Python 解释器 (CPython) 解析复杂的大文件的速度不是很快。

    注意values[i]字符串,所以self.timestampself.box。它们不应该是整数/浮点数吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-11-12
      • 2021-10-25
      • 2018-06-13
      • 2016-02-29
      • 1970-01-01
      • 2015-10-06
      • 1970-01-01
      相关资源
      最近更新 更多