I have an np array that looks like this:
arr = np.array([
[(1,1), (2,2), (3,3)],
[(1,1), (2,2), (3,3)],
[(1,1), (2,2), (3,3)]
])
I am doing some element-wise operations which we will simplify as adding 1 to each element.
My operations require me to break the array down as such:
num_elements = arr.shape[1]
for i in list(range(num_elements)):
x = ([c[i][0] for c in arr])
y = ([c[i][1] for c in arr])
# do operations here (again, more complex in reality but for this example its just 1)
xp = [t 1 for t in x]
yp = [s 1 for s in y]
modified_xy = list(zip(xp,yp))
After the first iteration, this gives me:
[(2,2),
(2,2),
(2,2)
]
How do I do this to the entire arr
and result in:
new_arr = [
[(2,2), (3,3), (4,4)],
[(2,2), (3,3), (4,4)],
[(2,2), (3,3), (4,4)]
]
The output should have the same exact shape as the input arr.
CodePudding user response:
You must describe the "much more complex operation" you have in mind, at least in principle. Try to describe as succinctly as possible why you can't simply work directly on the array in a vectorized way.
For example, for the simple operation of adding a given dx, dy
to each "row" of your array, you can simply do:
dx, dy = 1, 1
new_arr = arr.copy()
new_arr = (dx, dy)
>>> new_arr
array([[[2, 2],
[3, 3],
[4, 4]],
[[2, 2],
[3, 3],
[4, 4]],
[[2, 2],
[3, 3],
[4, 4]]])
CodePudding user response:
First be careful with your array description:
If I copy-n-paste your array, the resulting array displays differently:
In [29]: arr = np.array([
...: [(1,1), (2,2), (3,3)],
...: [(1,1), (2,2), (3,3)],
...: [(1,1), (2,2), (3,3)]
...: ])
...:
In [30]: arr
Out[30]:
array([[[1, 1],
[2, 2],
[3, 3]],
[[1, 1],
[2, 2],
[3, 3]],
[[1, 1],
[2, 2],
[3, 3]]])
That's a (3,3,2) integer dtype array, not a (3,3) array of tuples.
A list from the same display:
In [32]: alist = [
...: [(1,1), (2,2), (3,3)],
...: [(1,1), (2,2), (3,3)],
...: [(1,1), (2,2), (3,3)]
...: ]
In [33]: alist
Out[33]: [[(1, 1), (2, 2), (3, 3)], [(1, 1), (2, 2), (3, 3)], [(1, 1), (2, 2), (3, 3)]]
Your iteration does not preserve modified_xy
from the loops, it just returns the last. That's probably not what you want. Have you written much basic Python code? The code suggests you have lists in mind, not arrays. How about getting that working with a nested lists as I show in [33]?
In [38]: blist = []
...: for i in list(range(3)):
...: x = ([c[i][0] for c in alist])
...: y = ([c[i][1] for c in alist])
...: # do operations here (again, more complex in reality but for this e
...: xample its just 1)
...: xp = [t 1 for t in x]
...: yp = [s 1 for s in y]
...: modified_xy = list(zip(xp,yp))
...: blist.append(modified_xy)
...:
In [39]: blist
Out[39]: [[(2, 2), (2, 2), (2, 2)], [(3, 3), (3, 3), (3, 3)], [(4, 4), (4, 4), (4, 4)]]