Распараллеливание объектов назначения атрибутов в массиве numpy с использованием python - PullRequest
0 голосов
/ 18 февраля 2020

Я ищу способ распараллелить присвоение атрибутов объектам в массиве numpy, используя python. В приведенном ниже примере я обновляю атрибут (атрибут) каждого объекта ExampleObject в объектах, учитывая массив numpy того же размера объектов, содержащий новые значения атрибутов для каждого объекта.

import numpy as np
import math
import random


class ExampleObject():

    def __init__(self):
        self.attribute = random.random()

rows, columns = (5, 5)
objects = np.empty((rows, columns), dtype=object)
objects.flat = [ExampleObject() for _ in objects.flat]
attributes = np.zeros((rows, columns))
attributes = np.vectorize(lambda x: x.attribute)(objects)
new_attributes = np.random.rand(rows, columns)

for i in range(rows):
    for j in range(columns):
        objects[i][j].attribute = new_attributes[i][j]

Я знаю это может быть выполнено с использованием двух циклов for, и я включил код для этого выше, однако я не могу найти способ распараллеливания этого кода. Я пытался использовать многопроцессорность, однако, похоже, что он не может перехватить мой код.

1 Ответ

0 голосов
/ 18 февраля 2020

np.frompyfunc кажется самым удобным и быстрым инструментом для манипулирования массивами объектов пользовательских классов. Это может быть в два раза быстрее, чем понимание списка (не так уж много выгоды), и обрабатывает вещание.

Ваш класс с небольшим улучшением:

In [418]: class Foo(): 
     ...:     def __init__(self, val): 
     ...:         self.attribute = val 
     ...:     def __repr__(self): 
     ...:         return f'<Foo> {self.attribute}' 
     ...:                                                                                      
In [419]: Foo(1)                                                                               
Out[419]: <Foo> 1

Простое понимание списка - не плохой путь к go:

In [420]: alist = [Foo(i) for i in range(5)]                                                   
In [421]: alist                                                                                
Out[421]: [<Foo> 0, <Foo> 1, <Foo> 2, <Foo> 3, <Foo> 4]
In [422]: arr = np.array(alist)                                                                
In [423]: arr                                                                                  
Out[423]: array([<Foo> 0, <Foo> 1, <Foo> 2, <Foo> 3, <Foo> 4], dtype=object)

эквивалентно frompyfunc. Я определил __init__ для аргумента, чтобы я мог передать ему значение. Это можно изменить:

In [424]: arr = np.frompyfunc(Foo,1,1)(range(5))                                               
In [425]: arr                                                                                  
Out[425]: array([<Foo> 0, <Foo> 1, <Foo> 2, <Foo> 3, <Foo> 4], dtype=object)

Выборка значений:

In [426]: np.frompyfunc(lambda f: f.attribute,1,1)(arr)                                        
Out[426]: array([0, 1, 2, 3, 4], dtype=object)

Изменение значений (нельзя сделать это с лямбдой):

In [427]: def setfoo(foo, val): 
     ...:     foo.attribute = val 
     ...:                                                                                      
In [428]: np.frompyfunc(setfoo,2,0)                                                            
Out[428]: <ufunc '? (vectorized)'>
In [429]: _(arr, [10,np.ones((3,2)),np.arange(3),None, 'foobar'])                              
Out[429]: ()
In [430]: arr                                                                                  
Out[430]: 
array([<Foo> 10, <Foo> [[1. 1.]
 [1. 1.]
 [1. 1.]], <Foo> [0 1 2],
       <Foo> None, <Foo> foobar], dtype=object)

A 2d создание массива:

In [432]: M = np.frompyfunc(lambda i,j: Foo((i,j)), 2,1)(*np.ix_([1,2,3],[10,20]))             
In [433]: M                                                                                    
Out[433]: 
array([[<Foo> (1, 10), <Foo> (1, 20)],
       [<Foo> (2, 10), <Foo> (2, 20)],
       [<Foo> (3, 10), <Foo> (3, 20)]], dtype=object)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...