Given a matrix m and a pair of "counts" count_x and count_y I would like a new larger matrix that has every value in m repeated a different number of times. So, for example, the m[i,j] block in the new array would have size (count_y[i],count_x[j]).
Here is what I have figured out by looping:
count_x = [1,2,1]
count_y = [1,1,3]
matrix = np.array([[1,2,3],[4,5,6],[7,8,9]])
new_array = np.zeros((matrix.shape[0], sum(count_x)))
final_array = np.zeros((sum(count_y), sum(count_x)))
for row_n, row in enumerate(matrix):
new_row = [[row[i]]*nx for nx, i in zip(count_x, range(len(row)))]
unpacked_new_row = [i for j in new_row for i in j]
new_array[row_n] = unpacked_new_row
y_indices = [[i]*ny for ny, i in zip(count_y, range(len(count_y)))]
y_indices_unpacked = [i for j in y_indices for i in j]
for j in range(final_array.shape[0]):
final_array[j,:] = new_array[y_indices_unpacked[j],:]
print(final_array)
The output for this example is
[[1 2 2 3]
[4 5 5 6]
[7 8 8 9]
[7 8 8 9]
[7 8 8 9]]
How can this be accomplished without looping?
>Solution :
Repeat lets you specify different numbers of repeats:
In [100]: count_x = [1,2,1]
...: count_y = [1,1,3]
...:
...: arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
In [101]: arr.repeat(count_y, axis=0)
Out[101]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[7, 8, 9],
[7, 8, 9]])
In [102]: arr.repeat(count_y, axis=0).repeat(count_x, axis=1)
Out[102]:
array([[1, 2, 2, 3],
[4, 5, 5, 6],
[7, 8, 8, 9],
[7, 8, 8, 9],
[7, 8, 8, 9]])