Можно ли работать с несколькими TXT-файлами одновременно в python? - PullRequest
0 голосов
/ 30 апреля 2020

У меня есть 1080 .txt файлов, каждый из которых содержит более 100 тыс. Строк значений в трех столбцах. Я должен выполнить среднее значение первого столбца в каждом из этих файлов .txt.

Любой метод, выполняющий циклы, оказывается слишком медленным, так как numpy.loadtxt одновременно загружает только один файл.

Кикер в том, что у меня 38 таких папок, над которыми мне нужно выполнить эту операцию. Итого 38 * 1030 файлов. Использование модуля time для расчета времени вычислений для каждого numpy.loadtxt дает мне около 1,7 секунды. Таким образом, общее время работы над всеми папками составляет более 21 часа, что кажется слишком большим временем.

Поэтому у меня возникает вопрос, существует ли способ выполнять несколько операций одновременно, имея возможность открывать несколько txt файлы и среднее значение по первому столбцу. Затем также возможность сохранять это среднее в соответствующем порядке текстовых файлов, так как порядок важен.

Поскольку я начинающий, я не уверен, является ли это даже самым быстрым способом. Заранее спасибо.


    import numpy as np
    import glob
    import os

    i = 0 
    while i < 39:

        source_directory = "something/" + str(i)    #Go to specific folder with the numbering

        hw_array = sorted(glob.glob(source_directory + "/data_*.txt"))  # read paths of 1080 txt files

        velocity_array = np.zeros((30,36,3))

        for probe in hw_array:

            x = 35 - int((i-0.0001)/30)         #describing position of the probes where velocities are measured
            y = (30 - int(round((i)%30)))%30

            velocity_column = np.loadtxt(data_file, usecols=(0))    #step that takes most time
            average_array = np.mean(velocity_column, axis=0)

            velocity_array[y,x,0] = average_array
            velocity_array[y,x,1] = y*(2/29)
            velocity_array[y,x,2] = x*0.5

        np.save(r"C:/Users/md101/Desktop/AE2/Project2/raw/" + "R29" + "/data" + "R29", velocity_array) #save velocity array for use in later analysis
        i += 1

Ответы [ 2 ]

0 голосов
/ 30 апреля 2020

Вполне возможно написать функцию, которая загружает файлы из каталога, и порождает один multiprocessing и выполняет его почти в 1/39 от времени, которое требовалось. Или не распараллеливать по каталогу, а по файлу и ставить в очередь работу и читать из этой рабочей очереди.

Какой-то псевдокод:

pool = multiprocessing.Pool()

workers = []
for d in os.listdir("."):
  for f in os.listdir(d):
    workers.append(pool.apply_async(counter_function_for_file, (os.path.join(d, f),))

s = sum(worker.get() for worker in workers)

... и поместить свой код для чтение из файла в этой функции counter_function_for_file(filename).

0 голосов
/ 30 апреля 2020

Python имеет довольно медленный ввод-вывод, и большая часть вашего времени тратится на общение с операционной системой и другие расходы, связанные с открытием файлов.

Потоки в python странны и дают только улучшение в определенных ситуациях. Вот почему это хорошо для вашего случая. Как работает многопоточность в Python, так это то, что поток будет делать что-то, если у него есть разрешение (это называется получением GIL или глобальной блокировкой интерпретатора. Читайте об этом). Пока он чего-то ждет, например ввода / вывода, он передаст GIL другому потоку. Это позволит вашим файлам работать (усредняя первую строку), пока у него есть GIL, и когда файл открывается, он передает GIL другому файлу для выполнения операций

...