[英]Creating plots with multiprocessing and time.strftime() doens't work properly
我正在嘗試使用多處理並行運行我的腳本來創建繪圖。 我在這里為我的問題創建了 2 個示例腳本,因為帶有計算部分的實際主腳本會太長。 在 script0.py 中,您可以看到我啟動實際 script1.py 的多處理部分,該部分並行執行 4 次。 在這個例子中,它只是創建了一些隨機散點圖。
腳本0.py:
import multiprocessing as mp
import os
def execute(process):
os.system(f"python {process}")
if __name__ == "__main__":
proc_num = 4
process= []
for _ in range(proc_num):
process.append("script1.py")
process_pool = mp.Pool(processes= proc_num)
process_pool.map(execute, process)
腳本1.py:
#just a random scatterplot, but works for my example
import time
import numpy as np
import matplotlib.pyplot as plt
import os
dir_name = "stackoverflow_question"
plot_name = time.strftime("Plot %Hh%Mm%Ss") #note the time.strftime() function
if not os.path.exists(f"{dir_name}"):
os.mkdir(f"{dir_name}")
N = 50
x = np.random.rand(N)
y = np.random.rand(N)
colors = np.random.rand(N)
area = (30 * np.random.rand(N))**2
plt.scatter(x,y, s=area, c=colors, alpha=0.5)
#plt.show()
plt.savefig(f"{dir_name}/{plot_name}", dpi = 300)
重要的是,我按其創建時間命名 plot
plot_name = time.strftime("繪圖 %Hh%Mm%Ss")
所以這會創建一個類似“Plot 16h39m22s”的字符串。 到目前為止一切順利......現在到我的實際問題,我意識到在並行啟動進程時。 有時 plot 名稱相同,因為 time.strftime() 創建的時間戳相同,因此可能會發生 script1.py 的一個實例覆蓋另一個已創建的 plot 的情況。
在我遇到這個確切問題的工作腳本中,我生成了大量數據,因此我需要根據它們的生成日期和時間來命名我的圖和 CSV。
我已經想過在 script1.py 被調用時給它一個變量,但我不知道如何實現這一點,因為我剛剛了解了多處理庫。 但是這個變量也必須改變,否則我會遇到同樣的問題。
有人對我如何實現這一點有更好的了解嗎? 非常感謝你。
我提出這些方法:
歡迎來到本站。 幾個想法...
首先,您沒有遵循multiprocessing
模塊中關於如何使用Pool
的指南。 您應該在上下文管理器中with(...)...
那里有很多例子。 請參閱 dox 中的紅色警告:
https://docs.python.org/3/library/multiprocessing.html#module-multiprocessing.pool
此外,使用os.system
調用有點奇怪/不安全。 為什么不將繪圖例程放入同一模塊或不同模塊中的標准 function 中並導入它? 這將允許您向 function 傳遞附加信息(如一個好的標簽)。 我希望像這樣的東西,其中source
是數據文件或外部源......
def make_plot(source, output_file_name, plot_label):
# read the data source
# make the plot
# save it to the output path...
就 label 而言,如果您在同一個“秒”內啟動這些進程,當然會有重疊,因此您可以選擇 append label 或類似進程號的其他信息數據源,或使用相同的時間戳,但將 output 放在唯一的文件夾中,如另一個答案中所建議的那樣。
我會想這樣的事情......
from multiprocessing import Pool
import time
def f(data, output_folder, label):
# here data is just an integer, in yours, it would be the source of the graph data...
val = data * data
# the below is just example... you could just use your folder making/saving routine...
return f'now we can save {label} in folder {output_folder} with value: {val}'
if __name__ == '__main__':
with Pool(5) as p:
folders = ['data1', 'data2', 'data3']
labels = [time.strftime("Plot %Hh%Mm%Ss")]*3
x_s = [1, 2, 3]
output = p.starmap(f, zip(x_s, folders, labels))
for result in output:
print(result)
now we can save Plot 08h55m17s in folder data1 with value: 1
now we can save Plot 08h55m17s in folder data2 with value: 4
now we can save Plot 08h55m17s in folder data3 with value: 9
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.