# From ND to 1D arrays

## Question:

Say I have an array `a`:

``````a = np.array([[1,2,3], [4,5,6]])

array([[1, 2, 3],
[4, 5, 6]])
``````

I would like to convert it to a 1D array (i.e. a column vector):

``````b = np.reshape(a, (1,np.product(a.shape)))
``````

but this returns

``````array([[1, 2, 3, 4, 5, 6]])
``````

which is not the same as:

``````array([1, 2, 3, 4, 5, 6])
``````

I can take the first element of this array to manually convert it to a 1D array:

``````b = np.reshape(a, (1,np.product(a.shape)))
``````

but this requires me to know how many dimensions the original array has (and concatenate ’s when working with higher dimensions)

Is there a dimensions-independent way of getting a column/row vector from an arbitrary ndarray?

Use np.ravel (for a 1D view) or np.ndarray.flatten (for a 1D copy) or np.ndarray.flat (for an 1D iterator):

``````In : a = np.array([[1,2,3], [4,5,6]])

In : b = a.ravel()

In : b
Out: array([1, 2, 3, 4, 5, 6])
``````

Note that `ravel()` returns a `view` of `a` when possible. So modifying `b` also modifies `a`. `ravel()` returns a `view` when the 1D elements are contiguous in memory, but would return a `copy` if, for example, `a` were made from slicing another array using a non-unit step size (e.g. `a = x[::2]`).

If you want a copy rather than a view, use

``````In : c = a.flatten()
``````

If you just want an iterator, use `np.ndarray.flat`:

``````In : d = a.flat

In : d
Out: <numpy.flatiter object at 0x8ec2068>

In : list(d)
Out: [1, 2, 3, 4, 5, 6]
``````
``````In : b = np.reshape(a, (np.product(a.shape),))

In : b
Out: array([1, 2, 3, 4, 5, 6])
``````

or, simply:

``````In : a.flatten()
Out: array([1, 2, 3, 4, 5, 6])
``````

Although this isn’t using the np array format, (to lazy to modify my code) this should do what you want… If, you truly want a column vector you will want to transpose the vector result. It all depends on how you are planning to use this.

``````def getVector(data_array,col):
vector = []
imax = len(data_array)
for i in range(imax):
vector.append(data_array[i][col])
return ( vector )
a = ([1,2,3], [4,5,6])
b = getVector(a,1)
print(b)

Out>[2,5]
``````

So if you need to transpose, you can do something like this:

``````def transposeArray(data_array):
# need to test if this is a 1D array
# can't do a len(data_array) if it's 1D
two_d = True
if isinstance(data_array, list):
dimx = len(data_array)
else:
dimx = 1
two_d = False
dimy = len(data_array)
# init output transposed array
data_array_t = [[0 for row in range(dimx)] for col in range(dimy)]
# fill output transposed array
for i in range(dimx):
for j in range(dimy):
if two_d:
data_array_t[j][i] = data_array[i][j]
else:
data_array_t[j][i] = data_array[j]
return data_array_t
``````

### For list of array with different size use following:

``````import numpy as np

# ND array list with different size
a = [,[2,3,4,5],[6,7,8]]

# stack them
b = np.hstack(a)

print(b)
``````

### Output:

`[1 2 3 4 5 6 7 8]`

One of the simplest way is to use `flatten()`, like this example :

`````` import numpy as np

batch_y =train_output.iloc[sample, :]
batch_y = np.array(batch_y).flatten()
``````

My array it was like this :

``````    0
0   6
1   6
2   5
3   4
4   3
.
.
.
``````

After using `flatten()`:

``````array([6, 6, 5, ..., 5, 3, 6])
``````

It’s also the solution of errors of this type :

``````Cannot feed value of shape (100, 1) for Tensor 'input/Y:0', which has shape '(?,)'
``````

I wanted to see a benchmark result of functions mentioned in answers including unutbu’s.

Also want to point out that numpy doc recommend to use `arr.reshape(-1)` in case view is preferable. (even though `ravel` is tad faster in the following result)

TL;DR: `np.ravel` is the most performant (by very small amount).

## Benchmark

Functions:

numpy version: ‘1.18.0’

### Execution times on different `ndarray` sizes

``````+-------------+----------+-----------+-----------+-------------+
|  function   |   10x10  |  100x100  | 1000x1000 | 10000x10000 |
+-------------+----------+-----------+-----------+-------------+
| ravel       | 0.002073 |  0.002123 |  0.002153 |    0.002077 |
| reshape(-1) | 0.002612 |  0.002635 |  0.002674 |    0.002701 |
| flatten     | 0.000810 |  0.007467 |  0.587538 |  107.321913 |
| flat        | 0.000337 |  0.000255 |  0.000227 |    0.000216 |
+-------------+----------+-----------+-----------+-------------+
``````

### Conclusion

`ravel` and `reshape(-1)`‘s execution time was consistent and independent from ndarray size.
However, `ravel` is tad faster, but `reshape` provides flexibility in reshaping size. (maybe that’s why numpy doc recommend to use it instead. Or there could be some cases where `reshape` returns view and `ravel` doesn’t).
If you are dealing with large size ndarray, using `flatten` can cause a performance issue. Recommend not to use it. Unless you need a copy of the data to do something else.

### Used code

``````import timeit
setup = '''
import numpy as np
nd = np.random.randint(10, size=(10, 10))
'''

timeit.timeit('nd = np.reshape(nd, -1)', setup=setup, number=1000)
timeit.timeit('nd = np.ravel(nd)', setup=setup, number=1000)
timeit.timeit('nd = nd.flatten()', setup=setup, number=1000)
timeit.timeit('nd.flat', setup=setup, number=1000)
``````

Best and fastest among all the suggested solutions: `np.reshape()`

``````%timeit img1ary = np.reshape(img2ary,(np.product(img2ary.shape),1))
9.3 µs ± 69.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%timeit img1ary = img2ary.ravel()
157 ns ± 1.32 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

%timeit img1ary = img2ary.flatten()
961 ns ± 5.77 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
``````
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.