質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
並列処理

複数の計算が同時に実行される手法

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

3700閲覧

Pythonでjoblibの繰り返しの数を増やすとエラーが出てしまいます

simpkins

総合スコア5

並列処理

複数の計算が同時に実行される手法

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2021/05/18 08:20

編集2021/05/18 08:33

前提・実現したいこと

乱数を用いた線形計画法を解く際に一回の計算を関数としてそれを指定した回数繰り返すプログラムをjoblibを用いて書きました。
しかし,プログラムの内容自体を変えずに繰り返しの回数を増やした際に以下のエラーが発生します。ちなみに繰り返し数が100回くらいだとエラーが出ずにきちんと動作して,1000回で試したところエラーが出ました。
プログラム自体は繰り返し数が少なければ普通に動くので問題ないと思うのですが,回数を増やした途端エラーがなぜ出るのかわかりません。簡単なプログラムだと繰り返しの数を1000回以上にしてもエラーは出ないのでプログラムが長いことなどが原因なのでしょうか。

よろしくお願いします。

発生している問題・エラーメッセージ

RemoteTraceback Traceback (most recent call last) _RemoteTraceback: """ Traceback (most recent call last): File "C:\ProgramData\Anaconda3\lib\site-packages\joblib\externals\loky\process_executor.py", line 431, in _process_worker r = call_item() File "C:\ProgramData\Anaconda3\lib\site-packages\joblib\externals\loky\process_executor.py", line 285, in __call__ return self.fn(*self.args, **self.kwargs) File "C:\ProgramData\Anaconda3\lib\site-packages\joblib\_parallel_backends.py", line 595, in __call__ return self.func(*args, **kwargs) File "C:\ProgramData\Anaconda3\lib\site-packages\joblib\parallel.py", line 263, in __call__ for func, args, kwargs in self.items] File "C:\ProgramData\Anaconda3\lib\site-packages\joblib\parallel.py", line 263, in <listcomp> for func, args, kwargs in self.items] File "<ipython-input-10-476ba194835d>", line 302, in monte IndexError: list index out of range """ The above exception was the direct cause of the following exception: IndexError Traceback (most recent call last) <ipython-input-10-476ba194835d> in <module> 346 347 --> 348 r = Parallel(n_jobs=16, verbose=1)(delayed(monte)() for k in range(n)) 349 350 print(len(r)) C:\ProgramData\Anaconda3\lib\site-packages\joblib\parallel.py in __call__(self, iterable) 1059 1060 with self._backend.retrieval_context(): -> 1061 self.retrieve() 1062 # Make sure that we get a last message telling us we are done 1063 elapsed_time = time.time() - self._start_time C:\ProgramData\Anaconda3\lib\site-packages\joblib\parallel.py in retrieve(self) 938 try: 939 if getattr(self._backend, 'supports_timeout', False): --> 940 self._output.extend(job.get(timeout=self.timeout)) 941 else: 942 self._output.extend(job.get()) C:\ProgramData\Anaconda3\lib\site-packages\joblib\_parallel_backends.py in wrap_future_result(future, timeout) 540 AsyncResults.get from multiprocessing.""" 541 try: --> 542 return future.result(timeout=timeout) 543 except CfTimeoutError as e: 544 raise TimeoutError from e C:\ProgramData\Anaconda3\lib\concurrent\futures\_base.py in result(self, timeout) 423 raise CancelledError() 424 elif self._state == FINISHED: --> 425 return self.__get_result() 426 427 self._condition.wait(timeout) C:\ProgramData\Anaconda3\lib\concurrent\futures\_base.py in __get_result(self) 382 def __get_result(self): 383 if self._exception: --> 384 raise self._exception 385 else: 386 return self._result IndexError: list index out of range

該当のソースコード

from __future__ import division import pulp from pulp import LpVariable, LpProblem, LpStatus, lpSum, value import random import pandas as pd import itertools import numpy as np from joblib import Parallel, delayed from pandas import Series import matplotlib.pyplot as plt import locale import datetime as dt from tqdm import tqdm import time import datetime from matplotlib.ticker import ScalarFormatter csv = pd.read_csv('(修正版)需要とpv5.csv', parse_dates=[0], index_col=0) df=csv.resample('H').mean() # 変数(連続)を宣言 T=24*365 #時間 #Cbuy = list(df['料金']) Cbuy = 15.0 Csell = 8.0 PVinterest=(1+0.03)**(30)/30 Binterest=(1+0.03)**(20)/20 # PV parameters Cpv_inv=250000 #PV年間投資コスト Ppv_rated =LpVariable('Ppv_rated', 0, 10000) Ppv= [LpVariable('Ppv_{}'.format(i), 0, None) for i in range(T)] eff=0.9 CCB_inv=30000 CPB_inv=120000 Bcap= [LpVariable('Bcap_{}'.format(i), 0, None) for i in range(T)] Pb= [LpVariable('Pb_{}'.format(i), None, None) for i in range(T)] n = 1000 #繰り返し数 ←この部分を変えただけでエラーが出ます。 Pgrid= [LpVariable('Pgrid_{}'.format(i), None, None) for i in range(T)] Cp = [LpVariable('Cp_{}'.format(i), None, None) for i in range(T)] Pgrid_max = LpVariable('Pgrid_max',0,480) objective=[LpVariable('objective_{}'.format(k), None, None) for k in range(n)] #ここからは災害時の設定 ccsv = pd.read_csv('需要とPVと人数推定_2021_03_22.csv', parse_dates=[0], index_col=0) ddf = ccsv.resample('H').mean() covid_19 = 0 blackout_start_time = 0 R_dem_OA = 0.2 #関数 def monte(): x = random.randrange(31, 61, 5) Bcap_max = random.randrange(26, 176, 25) Pb_max = random.randrange(17, 167, 25) df=csv.resample('H').mean() df = df.reset_index() df['weekday'] =df['時間'].dt.weekday df = df.set_index("時間") df.loc[df['weekday'] < 5 , 'weekday'] = 1 df.loc[df['weekday'] >= 5, 'weekday'] = 0 def shuffle_days(df_month): groups = [df for _, df in df_month.groupby('D')] random.shuffle(groups) return pd.concat(groups).reset_index(drop=True) df = df.reset_index() df['Y'] = df['時間'].dt.year df['M'] = df['時間'].dt.month df['D'] = df['時間'].dt.day df = df.groupby(['Y', 'M','weekday']).apply(shuffle_days) df = df.drop(['Y', 'M', 'D','weekday'], axis=1).reset_index(drop=True) demand = list(df['demand']) Ppv5 = list(df['pv_5']) Cbuy = 15 d_term = [1,2,3] tt = random.choice(d_term) TT = 24 * tt BBcap = [LpVariable('BBcap_{}'.format(i), None, None) for i in range(TT)] PPb = [LpVariable('PPb_{}'.format(i), None, None) for i in range(TT)] ddemand = [LpVariable('ddemand_{}'.format(i), 0, None) for i in range(TT)] Psf = [LpVariable('Psf_{}'.format(i), None, None) for i in range(TT)] Cbd = [LpVariable('Cbd_{}'.format(i), None, None) for i in range(TT)] Csf = [LpVariable('Csf_{}'.format(i), None, None) for i in range(TT)] Emp = [LpVariable('Emp_{}'.format(i), None, None) for i in range(TT)] Eva = 10 #避難者数(Evacuee) ) x0 = [LpVariable('x0_{}'.format(i), 0, None) for i in range(TT)] x1 = [LpVariable('x1_{}'.format(i), 0, None) for i in range(TT)] x2 = [LpVariable('x2_{}'.format(i), 0, None) for i in range(TT)] x3 = [LpVariable('x3_{}'.format(i), 0, None) for i in range(TT)] SoC0_before = [0,0,0,0,0,0,0,0,0,0,0,0,0,0.3551,16.572,0,0,0,0,0,0,0,0,0] SoC0_after = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,47.3011,50.3314,49.4792,0,0,0,0,0,0,0] Rev_year = 4000000000 Cbuy = 15 Cp_end = LpVariable('Cp_end',None,None) C0_before = 0.1 C0_after = 0 C1 = 0.5 C2 = 1 C3_before = 2 C3_after = 2.1 X0_before = 0.3 X0_after = 0.6 #コロナ禍 X1_before = 0.4 X1_after = 0.2 #コロナ禍 X2_before = 0.2 X2_after = 0.1 #コロナ禍 X3 = 0.1 rate_sf = 7 R_dem_OA = 0.2 date = random.randint(1, 365) s = date * 24 + blackout_start_time ddf2 = ddf[s:s+TT] demand_usual_before = list(ddf2['demand_usual']) demand_usual_after = list(ddf2['demand_usual_covid_19']) PPpv5 = list(ddf2['pv_5']) PPpv = [n * x for n in PPpv5] #PV発電量 demand_hour_Emp = list(ddf2['demand_hour_Emp']) Emp_usual_before = list(ddf2['Emp_usual']) Emp_usual_after = list(ddf2['Emp_usual_covid_19']) PPpv = [n * x for n in PPpv5] BL = list(ddf2['Base']) Emp_total = sum(ddf['Emp_usual']) Rev_hour_Emp = Rev_year / Emp_total # if covid_19 == 0 demand_usual = demand_usual_before Emp_usual = Emp_usual_before SoC0 = SoC0_before[blackout_start_time] / 100 C0 = C0_before C3 = C3_before X0 = X0_before X1 = X1_before X2 = X2_before else: demand_usual = demand_usual_after Emp_usual = Emp_usual_after SoC0 = SoC0_after[blackout_start_time] / 100 C0 = C0_after C3 = C3_after X0 = X0_after X1 = X1_after X2 = X2_after CX_elec = C0 * X0 + C1 * X1 + C2 * X2 + C3 * X3 # Optimisation problem 目的関数(最小化) prb = LpProblem('Battery Operation') # Objective 目的関数 objective1= lpSum(Cp) +Binterest*(CCB_inv*Bcap_max+CPB_inv*Pb_max)+PVinterest*Cpv_inv*Ppv_rated +1700*12*Pgrid_max objective2 = Cp_end + lpSum(Cbd) + lpSum(Csf) prb += objective1 + objective2 # Constraints 制約 prb += Ppv_rated == 9*x for i in range(T): if Pgrid[i]>=0: Cp[i] == Cbuy * Pgrid[i] else: Cp[i] == Csell * Pgrid[i] prb+= Ppv[i]== Ppv5[i]* x ###ここからは災害の制約 for i in range(TT): prb += Cbd[i] == Rev_hour_Emp * Emp_usual_before[i] * (CX_elec - (C0 * x0[i])\ - (C1 * x1[i]) - (C2 * x2[i]) - (C3 * x3[i])) prb.solve() cost = pulp.value(objective1) ccost = pulp.value(objective2) allcost = cost + ccost return cost ,ccost,date,Bcap_max, allcost, tt r = Parallel(n_jobs=16, verbose=1)(delayed(monte)() for k in range(n)) print(len(r)) asd=pd.DataFrame(r) asd.columns = ['平時','災害時','災害日','蓄電池容量','総コスト','災害日数'] print(asd[:10]) print("総コストの最大値{}".format(max(asd['総コスト']))) print("総コストの最小値{}".format(min(asd['総コスト']))) plt.figure(figsize=(12,8)) asd['総コスト'].hist(density=True); plt.gca().yaxis.set_major_formatter(ScalarFormatter(useMathText=True))#y軸小数点以下3桁表示 plt.gca().xaxis.set_major_formatter(ScalarFormatter(useMathText=True))#y軸小数点以下3桁表示 plt.show()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jbpb0

2021/05/18 09:39 編集

> File "<ipython-input-10-476ba194835d>", line 302, in monte IndexError: list index out of range monte関数内のどこかの行で、リストの要素数外へのアクセスが発生してるのではないですかね
jbpb0

2021/05/18 14:20

jupyterで実行してますか? もしそうなら、jupyterだとエラーになってる302行目がどこかがわかりにくいので、jupyterから普通の「*.py」ファイルにエクスポートして実行して、エラーが何行目で出るのか確認して、その行を調べたら、いかがでしょうか
guest

回答2

0

ベストアンサー

joblibなしで試してみて、再現するかどうか確認し、joblibなしならいけるのであればバックエンドの設定とかをいじってみる手があります。

あと、100回での実行を10回やって一回でもエラーが出るなら、特定の乱数の状況下でエラーになるロジックになっていないか見直すべきでしょう。

投稿2021/05/19 01:57

編集2021/05/19 01:58
hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hayataka2049

2021/05/19 02:00

random.choiceとrandom.randintがあるので、疑わしいのはそこらへんな気がする。特定の組み合わせのときデータが揃ってないとかで何らかの形でリスト外を叩くんじゃないか?
simpkins

2021/05/19 03:09

回答ありがとうございます。デバッガというのを使ったことがないですがやってみます。
hayataka2049

2021/05/19 03:17 編集

その際はParallelから普通の内包表記に直してやってみてください。 # たぶんマルチプロセスだとpdbがうまく動きません。 その際は「Parallelをやめたらエラーが出なくなった」的現象が起きないか先に確認を。
hayataka2049

2021/05/19 03:19

首尾よく(?)エラーが発生してデバッガに入れたら、lでエラーが出ているコード位置を特定、 あと、対話的に変数の中身を見れるので、とりあえずttとdateの値を拾ってみる。他の変数も気になると思うので見てみる。 で、この回答に書いた仮説(二番目)は検証できるはずです。
simpkins

2021/05/19 10:07

内包表記でやってみたところnが小さければ問題なく動作しますが,nを大きくするとエラーが出ます。エラーではprb += Cbd[i] == Rev_hour_Emp * Emp_usual_before[i] * (CX_elec - (C0 * x0[i]) - (C1 * x1[i]) - (C2 * x2[i]) - (C3 * x3[i]))のところにエラーがあるようですがまだ原因がわかっていない状態です。 それと,対話的に変数の中身を見れるというのがよくわからなかったので変数に見方などを教えていただけないでしょうか。
hayataka2049

2021/05/19 13:56

たとえばpdbが立ち上がったときにiと打ち込めばiの値が見れます(そのまま)。
simpkins

2021/05/20 06:02

エラーの原因がdate = random.randint(1, 365)の部分であることがわかりました。乱数の設定値がおかしかったみたいです。ご迷惑をおかけしました。
guest

0

こんばんは。

問題文読ませていただきました。

nで検索してnに関係するあまり良くないコードがありましたので、ここが原因かなと思っております。

Python

1n = 1000 2 3def monte(): 4 # 一度nを定数宣言しているものとここでのnがかぶっている気がする。 5 # PPpv = [hoge * x for hoge in PPpv5] とかで動くのか知りたいです。 6 PPpv = [n * x for n in PPpv5] #PV発電量

ご確認のほど、よろしくお願いいたします。????‍♂️

投稿2021/05/18 10:16

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

simpkins

2021/05/18 11:55

回答ありがとうございます。 ご指摘いただいた部分を修正しましたがエラーが出てしまいました。ちなみに修正したものをn=10で試したところ問題なく動作しました。
jbpb0

2021/05/18 12:59

PPpv = [n * x for n in PPpv5] の「n」は関数内のローカルな変数なので、関数外の n = 1000 の「n」とは別のものなんじゃないですかね
simpkins

2021/05/18 14:15

そうですね。nが小さい数字の時はエラーも出ずにきちんと結果が出るのにnを大きくしただけでエラーが出てしまうのが謎なんですよね。
退会済みユーザー

退会済みユーザー

2021/05/19 00:31

あ、本当ですね、、 失礼いたしました。????‍♂️ def monte()内のfor文を回しているところでバグを起こしていると思われますので、n=1000とした場合に、どこでエラーが発生しているのかprintとexit()を使って確認いただけますか?????‍♂️
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問