-1

I found multiple questions with almost the same title but none of them have a working code.

so I have the following 1D array a, once I reshape it to 3d array b, and then reshape it back to 1D array.

import numpy as np

depth = 2
row = 3
col = 4

a = np.arange(24)
b = a.reshape((depth, row, col))
c = np.zeros(row*col*depth)

print(a)
print(b)

index = 0

for i in range(depth):
    for j in range(row):
        for k in range(col):
            c[k+ j * row + i * (col*row)] = b[i][j][k]  # ???
            # c[k + row * (j + depth * i)] = b[i][j][k]
            # c[index] = b[i][j][k]
            # index+=1

print(c)

# [ 0.  1.  2.  4.  5.  6.  8.  9. 10. 11.  0.  0. 12. 13. 14. 16. 17. 18.
# 20. 21. 22. 23.  0.  0.]


I don't get Flat[x + WIDTH * (y + DEPTH * z)] = Original[x, y, z] in this case.

EDIT

I am using this code (the equivalent) in a CUDA code, so I need the loops. I am not going to use any numpy magic functions.

Abolfazl
  • 1,047
  • 2
  • 12
  • 29

2 Answers2

1

Simply reshape again to your original dimension or flatten the resulting array:

depth = 2
row = 3
col = 4
a = np.arange(24)
b = a.reshape((depth, row, col))
print(b.reshape((24,)))
print(b.flatten())

Output:

[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23]
FlyingTeller
  • 17,638
  • 3
  • 38
  • 53
  • no I need the indices, this is the trivial answer. – Abolfazl Mar 10 '22 at 11:51
  • 1
    Please rephrase then, because you stated "The input is a = [0 ..23], the output c should look like the initial array a", this output looks like the initial array `a` – FlyingTeller Mar 10 '22 at 11:52
1

That's because the array you created uses row-major order instead of column-major as you assumed

The correct way to compare is

depth = 2
row = 3
col = 4
a = np.arange(24)
b = a.reshape((depth, row, col))
b.strides

i,j,k = np.indices(b.shape)

assert(np.all(a[(i*row+j)*col+k] == b[i,j,k]))

If you want more information on how the matrix is arranged you can check b.strides = (48, 16, 4), this gives the coefficient (in bytes) of each index, i.e.g (i*48+j*16+k*4) is the offset of the element b[i,j,k].

This is the column-major order is called Fortran order and you can get numpy to reshape assuming it by passing order='F'

bf = a.reshape((depth, row, col), order='F')
assert(np.all(a[i + depth * (j + row * k)] == bf))

Then bf will be

array([[[ 0,  6, 12, 18],
        [ 2,  8, 14, 20],
        [ 4, 10, 16, 22]],

       [[ 1,  7, 13, 19],
        [ 3,  9, 15, 21],
        [ 5, 11, 17, 23]]])
Bob
  • 13,867
  • 1
  • 5
  • 27