I would like to create the following functions, but I would like to know how to loop any number of times.
1. As an argument, take two functions: (1) an arbitrary number of dimensions of numpy array, and (2) a processing corresponding to each dimension.
②All array elements are processed.However, the action is based on the function specified as the argument.
At this time, you do not know how to create any number of nested operations.
For example, if it's a 4D array, it's dirty, but
x = NDARRAY.shape
for i in range (x[0]):
for jin range (x[1]):
fork in range (x[2]):
for line range (x[3]):
You can do this, but what do you usually do when you're in n-dimensional?
Do I need knowledge of meta-programming?
This is an example implementation that recursively represents a nest of any depth.
実装Implementation Example <
import numpy as np
def loopoop(func, na, dims=None, indexes=[], level=0, no=0, first=True):
if dims is None:
dims = na.shape
if first:
indexes=[0]*len(dims)
iflen(dims)<=0:
func(na,indexes)
return
for i in range (dims[0]):
indexes [level] = i
loopoop(func, na, dims[1:], indexes=indexes, level=level+1, no=i, first=False)
def func1(na,indexes):
print("Hello:indexes="+str(indexes))
na = np.ndarray ((2,3,4,5))
loopoop(func1,na)
Processing name
loopoop
(1) Any number of dimensions of numpy array
na
Processing Name
loopoop
任意 Any number of numpy arrays
na
Caution
In KLC's answer, I think it would be advantageous in terms of speed to manage the multi-dimensional array data in one-dimensional array.
[Multidimensional]
Sizett[SIZE_1][SIZE_2][SIZE_3][SIZE_4]
Index tttt[i1][i2][i3][i4]
[1D]
Size t[SIZE_1*SIZE_2*SIZE_3*SIZE_4]
index t[i]
i=i1*SIZE_2*SIZE_3*SIZE_4
+ i2*SIZE_3*SIZE_4
+ i3*SIZE_4
+ i4
Calculate each index from i using the following formula:
i1=(i%(SIZE_1*SIZE_2*SIZE_3*SIZE_4)//(SIZE_2*SIZE_3*SIZE_4)
i2=(i%(SIZE_2*SIZE_3*SIZE_4)//(SIZE_3*SIZE_4)
i3=(i%(SIZE_3*SIZE_4))//(SIZE_4)
i4=(i%SIZE_4)
It would be good to use nditer with multi_index flag.
https://docs.scipy.org/doc/numpy/reference/generated/numpy.nditer.html
import numpy as np
x = np.random.randn(2,3)
it=np.nditer(x,flags=['multi_index'])
while not.finished:
# do something with x and it.multi_index
print(it.multi_index)
print(x[it.multi_index])
# move on
it.iternext()
(0,0)
0.23465161779473015
(0, 1)
0.22383801010291296
(0, 2)
-0.8051323435933129
(1, 0)
0.8931324229893808
(1, 1)
-0.4271553422304515
(1, 2)
-2.146703943718106
#Different dimensions of data
x = np.random.randn(2,3,2)
# The code below is exactly the same.
it=np.nditer(x,flags=['multi_index'])
while not.finished:
print(it.multi_index)
print(x[it.multi_index])
it.iternext()
(0,0,0)
0.30500812464361104
(0, 0, 1)
0.7671660280535492
(0, 1, 0)
-0.87198212525212
(0, 1, 1)
-0.6311542834847657
(0, 2, 0)
0.5198028854150701
(0, 2, 1)
0.8153458301759646
(1, 0, 0)
-0.7942063485178719
(1, 0, 1)
-1.568633897435036
(1, 1, 0)
-1.3299054158710617
(1, 1, 1)
-0.4096393538574391
(1, 2, 0)
-0.03538806394741229
(1, 2, 1)
0.5462354038739015
How about this?The idea is to generate subscripts and then scan all the elements in a single loop:
import it tools
import numpy as np
# main
def(A,g):
for idx in intertools.product (*[range(n) for n in A.shape]):
g(A,A[idx],*idx)
# callback
defh(Arr, Elm, *idx):
assert Arr [idx] == Elm
print('Arr[%s]=%f'%(str(idx), Elm))
# For example...
shape=(2,3,4,5)
X=np.range(np.product(shape)) .reshape(shape)
f(X,h)
Sample Output:
Arr[(0,0,0,0)] = 0.000000
Arr [(0,0,0,1)] = 1.000000
Arr [(0,0,0,2)] = 2.000000
Arr [(0,0,0,3)] = 3.000000
Arr [(0,0,0,4)] = 4.000000
...
© 2024 OneMinuteCode. All rights reserved.