#arrays #numpy #for-loop #parallel-processing #numpy-ndarray
#массивы #numpy #цикл for #параллельная обработка #numpy-ndarray
Вопрос:
Есть ли какой-либо способ (например, векторизация массивов numpy для параллельной обработки) удалить два цикла for и распараллелить этот код?
state_returns = np.zeros((10,10,dtype = np.ndarray))
value_function = np.zeros((10,10))
........................#further code to fill the values in array:state_returns
........................#Eg. state_returns = [[[1,2,3,..],[2,3,6,...],...],[[3,9,7,...],[5,8,6...],....],......]
........................#Eg. value_function = [[2,4,6,....],[6,5,7,...],....]
for i in range(10):
for j in range(10):
n = state_returns[i,j].shape[0]-1
value_function[i,j] = state_returns[i,j].sum()/n if (n!=0) else 0
Комментарии:
1. Немного запутался.
state_returns[i,j]
всегда является скаляром, поэтому использование.sum()
не имеет никакого смысла. Если вы лучше объясните, что вы пытаетесь сделать (реалистичный ввод, ожидаемый результат), я уверен, что мы сможем избавиться от циклов, используя базовую широковещательную передачу2. @PaulH Учитывая, что элементы state_returns имеют dtype = np.ndarray, следовательно, все элементы являются массивами numpy. Также все эти элементы массива, содержащиеся в массиве 10 * 10 numpy, могут иметь разные размеры (n,).
3. Если вы сделаете свой массив неровным, вам вообще не понадобится цикл
4. Пожалуйста, предоставьте надлежащий рабочий пример. Ваши образцы массивов являются неполными. Вы используете
np.zeros
неправильно. Прежде чем пытаться выполнять «параллельную обработку», попробуйте написать эффективный код numpy.
Ответ №1:
Если я прав, ваши вычисления являются поэлементными. То есть значение value_function[i,j]
не влияет на value_function[n,m]
for i != n
и j != m
. Это означает, что вы можете легко запускать свой код параллельно. Вот пример использования библиотеки потоков и 10 потоков (на самом деле я не проверял, работает ли код, но, надеюсь, вы поняли идею):
import threading
def calculation(i):
global state_returns, value_function
for j in range(10):
n = state_returns[i,j].shape[0]-1
value_function[i,j] = state_returns[i,j].sum()/n if (n!=0) else 0
if __name__ == '__main__':
t = []
for i in range(0, 10):
t.append(threading.Thread(target=calculation, args=(i,)))
for i in range(0, 10):
t[i].start()
for i in range(0, 10):
t[i].join()
Возможно, вам потребуется заблокировать переменные в def, если вы столкнулись с проблемами.