web-dev-qa-db-ja.com

forループを持つマルチプロセッシングプール

Forループに渡して一連の関数を実行するファイルのリストがあります。これを並列化する最も簡単な方法は何ですか?この正確なものがどこにあるかわからないと思います。実行中のファイルが1つだけだったので、現在の実装は正しくないと思います。私がこれまでに読んだいくつかのことから、これは完全に平行したケースになるはずだと思います。

古いコードは次のようなものです:

import pandas as pd
filenames = ['file1.csv', 'file2.csv', 'file3.csv', 'file4.csv']
for file in filenames:
    file1 = pd.read_csv(file)
    print('running ' + str(file))
    a = function1(file1)
    b = function2(a)
    c = function3(b)
    for d in range(1,6):
            e = function4(c, d)
    c.to_csv('output.csv')

(誤って)並列化されたコード

import pandas as pd
from multiprocessing import Pool
filenames = ['file1.csv', 'file2.csv', 'file3.csv', 'file4.csv']
def multip(filenames):
    file1 = pd.read_csv(file)
    print('running ' + str(file))
    a = function1(file1)
    b = function2(a)
    c = function3(b)
    for d in range(1,6):
            e = function4(c, d)
    c.to_csv('output.csv')

if __name__ == '__main__'
    pool = Pool(processes=4)
    runstuff = pool.map(multip(filenames))

私がやりたいこと(think)やりたいこと1つのファイル計算されるコアごと(おそらくプロセスごと?)私もやった

multiprocessing.cpu_count()

そして8を得ました(私はクワッドを持っているので、おそらくスレッドを考慮に入れています)。合計で約10個のファイルがあるので、プロセスごとに1つのファイルを配置して処理速度を上げることができれば、すばらしいでしょう残りの2つのファイルでも、第1ラウンドのプロセスが完了した後にプロセスが見つかるといいのですが。

編集:さらに明確にするために、関数(つまり、function1、function2など)は、それぞれのファイル内の他の関数(つまり、function1a、function1b)にもフィードされます。 importステートメントを使用して関数1を呼び出します。

次のエラーが発生します。

OSError: Expected file path name or file-like object, got <class 'list'> type

どうやらリストを渡すのは好きではないようですが、ifステートメントでfilenames [0]を実行したくないのは、1つのファイルしか実行しないためです。

8
Monty
import multiprocessing
names = ['file1.csv', 'file2.csv']
def multip(name):
     [do stuff here]

if __name__ == '__main__':
    #use one less process to be a little more stable
    p = multiprocessing.Pool(processes = multiprocessing.cpu_count()-1)
    #timing it...
    start = time.time()
    for file in names:
    p.apply_async(multip, [file])

    p.close()
    p.join()
    print("Complete")
    end = time.time()
    print('total time (s)= ' + str(end-start))

編集:if__name __ == '____main___'をこれに置き換えます。これはすべてのファイルを実行します:

if __name__ == '__main__':

    p = Pool(processes = len(names))
    start = time.time()
    async_result = p.map_async(multip, names)
    p.close()
    p.join()
    print("Complete")
    end = time.time()
    print('total time (s)= ' + str(end-start))
9
Monty