简体   繁体   中英

How does frompyfunc iterate over arrays?

I am working with large arrays representing a maze routing grid, each element is a Cell object with x,y attributes.

I am trying to use numpyfunc to initialize the coordinates in each cell with a vectorized function.

I have a vectorized function that sets the X coordinate of a Cell object:

def setCellX(self,c,x):
         c.setX(x)
         return c

setCellX_v = np.vectorize(self.setCellX)

I wrap this in frompyfunc

setCellX_npfunc = np.frompyfunc(self.setCellX_v,2,1)

When I call this on a 1-D array, it works as expected

Gx = 3000
Gy = 4000

# Initialize single row
R = np.array([Cell(0,y) for y in range(int(self.Gy))])

# Create array of X-coordinates
x_indices = [ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]

print R[6].x
0

setCellX_npfunc(R,x_indices)
print R[6].x
6

When I set R to be a 2-D array, I would expect for numpyfunc to iterate over each row and set the X values accordingly:

R = np.empty(shape=(20,20),dtype=object)
R.fill(Cell(0,0))

setCellX_npfunc(R,x_indices)
print(R[3][6].x)
19

Why wouldn't numpyfunc set the X values for each 1-d vector to the corresponding value in x_indices, like it did in the first example?

From your comments and suppose that Cell objects have x, y attributes and some other default attribute that doesn't come to play:

class Cell:
    def __init__(self, x,y):
        self.x = x
        self.y = y
    ...

Suppose you want a 100*100 array, initiate your array like this:

CellList = [[Cell(x,y) for y in range(100)] for x in range(100)]
# Optional translate it into np.array for easier indexing
CellArr = np.array(CellList)

This will return your 100*100 Cell array that has correct Cell elements. To verify:

CellArr[1,2].x
>>> 1

Note that numpy can't actually speed up your array much because Cell cannot actually go through C code when vectorizing. It could only be used for better indexing.

Vectorizing does not actually help your speed:

%%timeit
CellList = [[Cell(x,y) for y in range(100)] for x in range(100)]
# Optional translate it into np.array for easier indexing
CellArr = np.array(CellList)

>>> 24.2 ms ± 542 µs per loop

Vectorizing functions:

def vecX(c, x):
    c = Cell(x, 0)
    return c

def vecY(c, y):
    c.y = y
    return c

vec = np.vectorize(vecX)
vey = np.vectorize(vecY)

results:

%%timeit
l = []
n = np.zeros((100,100))
for i in range(len(n)):
    l.append(vec(n[i, :], i))
CellArr = np.vstack(l)
for j in range(len(CellArr)):
    vey(CellArr[:, j], j)

>>> 23.5 ms ± 5 ms per loop 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM