Yfir Cross
Yfir Cross

Reputation: 15

Numpy: Alternative ways to construct a matrix of points given the matrix of each coordinate separately

Let x, y, z be matrix representations, so that (x[i, j], y[i, j], z[i, j]) corresponds to a certain point.

Instead of having 3 variables we want to have just one variable (Points) where "Points[i,j]=(x[i,j],y[i,j],z[i,j])" and "Points[i,j,0]=x[i,j]"

Example:

import numpy as np
x = np.array([[1, 1],
              [2, 2]])
y = np.array([[1, 2],
              [1, 2]])
z = np.array([[3, 4],
              [5, 6]])
Points = np.array([[ [1, 1, 3], [1, 2, 4] ],
                     [2, 1, 5], [2, 2, 6] ]]) 

Currently I have thought of some solutions:

1st Solution:

from itertools import izip
Temp_List=[]
for xi, yi, zi in izip(x, y, z):
    Temp_List.append([(xij, yij, zij) for xij, yij, zij in izip(xi, yi, zi)])
Points=np.array(Temp_List)

I know that unpacking a tuple to pack it again is not very smart, but is for the sake of making it more readable and prepare the next solution

2nd Solution: # one-liner

from itertools import izip
Points=np.array([zip(xi, yi, zi) for xi, yi, zi in izip(x,y,z)])

I really like this option. However in this solution I'm concerned about readability. Maybe it's just me but I feel that it is not that obvious that the list comprehension generates something similar to Points in the Example. Unless you are familiarized with the difference between izip and zip.

It's obvious another solution is using indexes to iterate over the elements x, y and z like in other languages ( for i in xrange(...) : for j in xrange(...): do stuff ... )

Concluding: Is there another way of generating the Points variable from x,y,z using a numpy function ( or not) that improves either Readability, Memory consumption or performance ?

Upvotes: 1

Views: 293

Answers (1)

MaxNoe
MaxNoe

Reputation: 14987

You can use numpy's stack function:

import numpy as np

x = np.array([
    [1, 1],
    [2, 2],
])

y = np.array([
    [1, 2],
    [1, 2],
])

z = np.array([
    [3, 4],
    [5, 6],
])


points = np.stack([x, y, z], axis=2)

stack with the axis keyword supersedes the old vstack, hstack and dstack functions, which are now deprecated.

Upvotes: 2

Related Questions