简体   繁体   中英

Python: How can I force 1-element NumPy arrays to be two-dimensional?

I have piece of code that slices a 2D NumPy array and returns the resulting (sub-)array. In some cases, the slicing only indexes one element, in which case the result is a one-element array:

>>> sub_array = orig_array[indices_h, indices_w]
>>> sub_array.shape
(1,)

How can I force this array to be two-dimensional in a general way? Ie:

>>> sub_array.shape
(1,1)

I know that sub_array.reshape(1,1) works, but I would like to be able to apply it to sub_array generally without worrying about the number of elements in it. To put it in another way, I would like to compose a (light-weight) operation that converts a shape-(1,) array to a shape-(1,1) array, a shape-(2,2) array to a shape-(2,2) array etc. I can make a function:

def twodimensionalise(input_array):
     if input_array.shape == (1,):
         return input_array.reshape(1,1)
     else:
         return input_array

Is this the best I am going to get or does NumPy have something more 'native'?

Addition:

As pointed out in https://stackoverflow.com/a/31698471/865169 , I was doing the indexing wrong. I really wanted to do:

sub_array = orig_array[indices_h][:, indices_w]

This does not work when there is only one entry in indices_h , but combining it with np.atleast_2d suggested in another answer, I arrive at:

sub_array = np.atleast_2d(orig_array[indices_h])[:, indices_w]

It sounds like you might be looking for atleast_2d . This function returns a view of a 1D array as a 2D array:

>>> arr1 = np.array([1.7]) # shape (1,)
>>> np.atleast_2d(arr1)
array([[ 1.7]])
>>> _.shape
(1, 1)

Arrays that are already 2D (or have more dimensions) are unchanged:

>>> arr2 = np.arange(4).reshape(2,2) # shape (2, 2)
>>> np.atleast_2d(arr2)
array([[0, 1],
       [2, 3]])
>>> _.shape
(2, 2)

Are you sure you are indexing in the way you want to? In the case where indices_h and indices_w are broadcastable integer indexing arrays, the result will have the broadcasted shape of indices_h and indices_w . So if you want to make sure that the result is 2D, make the indices arrays 2D.

Otherwise, if you want all combinations of indices_h[i] and indices_w[j] (for all i, j), do eg a sequential indexing:

sub_array = orig_array[indices_h][:, indices_w]

Have a look at the documentation for details about advanced indexing.

When defining a numpy array you can use the keyword argument ndmin to specify that you want at least two dimensions. eg

arr = np.array(item_list, ndmin=2)
arr.shape
>>> (100, 1) # if item_list is 100 elements long etc

In the example in the question, just do

sub_array = np.array(orig_array[indices_h, indices_w], ndmin=2)
sub_array.shape
>>> (1,1)

This can be extended to higher dimensions too, unlike np.atleast_2d() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM