4

I want to fill an array with some number, the output should be like this:

[[x1, y1, z1],
 [x1, y2, z2],
 [x2, y1, z3],
 [x2, y2, z4],
 [x3, y1, z5],
 [x3, y2, z6]]

I have the data x, y, and z (lists) with 3 values x, 2 values of y and 6 values of z inside the data.

I tried to create a new array and then fill it with for or while loop, but I can't get it fully filled.

How can I do it in numpy with python without filling it manually?

4
  • 1
    stackoverflow.com/a/44409182/7957705 is maybe what you are looking for Commented Feb 23, 2019 at 7:07
  • @FatihKılıç I don't think it is, in his case, the output will be [[a1 b1] [a2 b2] ... [a5 b5]]. In my case, I want to pair each x with each y. Also, my data actually much larger than 2 x and 2 y Commented Feb 23, 2019 at 7:27
  • @Amri Rasyidi is there a typo in your output? The first column is x1,x1,x2,x2 or should it be x1,x2,x1,x2 ? Commented Feb 23, 2019 at 7:29
  • @AndyK nope, it is the output I want. Pair each x with each y that have z value Commented Feb 23, 2019 at 7:34

4 Answers 4

4

Using np.repeat and np.tile on x and y respectively to get the desired columns and then stacking them together with z into one array:

import numpy as np

x = [1, 2, 3]
y = [4, 5]
z = [6, 7, 8, 9, 10, 11]

a = np.array([np.repeat(x, 2), np.tile(y, 3), z]).T

result:

array([[ 1,  4,  6],
       [ 1,  5,  7],
       [ 2,  4,  8],
       [ 2,  5,  9],
       [ 3,  4, 10],
       [ 3,  5, 11]])
Sign up to request clarification or add additional context in comments.

3 Comments

I checked the dtype and it returns 'U10', can I still have the number format of the data?
@Amri Rasyidi what is your data like? Are the values of x,y and z of the same type? Are their values strings? It still should work.
I've found the solution to that dtype problem. I cast it into array then use astype to change the data type. Thank you!
3

For a pure Python solution, to work with any list size.

x = [11,12,13,14,15]
y = [21,23,24]
z = [31,32,33,34,35,36,37]

This verbose code:

tmp = []
for i in range(max(len(x), len(y), len(z))):
    for yy in y:
        tmp.append([x[i%len(x)], yy])

for i in range(len(tmp)):
    tmp[i].append((z[i%len(z)]))

Returns

# [[11, 21, 31],
#  [11, 23, 32],
#  [11, 24, 33],
#  [12, 21, 34],
#  [12, 23, 35],
#  [12, 24, 36],
#  [13, 21, 37],
#  [13, 23, 31],
#  [13, 24, 32],
#  [14, 21, 33],
#  [14, 23, 34],
#  [14, 24, 35],
#  [15, 21, 36],
#  [15, 23, 37],
#  [15, 24, 31],
#  [11, 21, 32],
#  [11, 23, 33],
#  [11, 24, 34],
#  [12, 21, 35],
#  [12, 23, 36],
#  [12, 24, 37]]

2 Comments

I'm sorry, but I've edited my question. Does it work with different size list of x and y?
@AmriRasyidi I edited leaving only the pure Python option do work with different sizes of any list.
1

You can achieve this using NumPy's meshgrid function to create a grid of all combinations of your x, y, and z values. Then, you can use numpy.column_stack to stack these arrays horizontally.

import numpy as np

# Your data
x = [1, 2, 3]
y = [1, 2]
z = [1, 2, 3, 4, 5, 6]

# Create a grid of all combinations
x_grid, y_grid, z_grid = np.meshgrid(x, y, z, indexing='ij')

# Reshape the grids to 1D arrays
x_flat = x_grid.flatten()
y_flat = y_grid.flatten()
z_flat = z_grid.flatten()

# Stack the arrays horizontally to create the final array
result_array = np.column_stack((x_flat, y_flat, z_flat))

print(result_array)

enter image description here

Comments

0

Decomposing the problem

Suppose X = [x_1,x_2,...,x_n], Y = [y_1,y_2,...,x_m] and Z=[z_1,z_2,...,z_nm], you want to:

  1. pair every X with every Y, first varying Y
  2. then pair the resulting sequence with Z, one by one, on the order they appear.

Cartesian product of X and Y

Pairing X and Y can be done using the product method from itertools, as in:

from itertools import product
X=[1,2]
Y=[3,4,5]
print(list(product(X,Y)))

This will return [(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), (2, 5)]

The itertools library doesn't return a list, but an iterable, so we can compose these iterables.

Pairing XY with Z

Now we have XY = [(x1,y_1), (x1,y_2), ... (x_1,y_m), (x_2, y_1), (x_2, y_2), ... , (x_2, y_m), ..., (x_n,y_m)] with n*m elements, and we want to pair them, respectively to Z=[z_1,z_2, ..., z_nm], to do that we can use a builtin function called zip which will pair them.

from itertools import product
X=[1,2]
Y=[3,4,5]
Z="abcdef"
XY=product(X,Y)
print(list(zip(XY, Z)))

Fixing the form

The last code will return [((1, 3), 'a'), ((1, 4), 'b'), ((1, 5), 'c'), ((2, 3), 'd'), ((2, 4), 'e'), ((2, 5), 'f')]. There is a slight deviation in the form: entries are on the form ((x,y),z) instead of [x,y,z], but we can fix that using a list comprehension:

from itertools import product
X=[1,2]
Y=[3,4,5]
Z="abcdef"
print([[x,y,z] for (x,y), z in zip(product(X,Y), Z)])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.