Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force numpy to create array of objects

I have an array:

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

and I want to create another array of shape=(1, 1) and dtype=np.object whose only element is x.

I've tried this code:

a = np.array([[x]], dtype=np.object)

but it produces an array of shape (1, 1, 2, 3).

Of course I can do:

a = np.zeros(shape=(1, 1), dtype=np.object)
a[0, 0] = x

but I want the solution to be easily scalable to greater a shapes, like:

[[x, x], [x, x]]

without having to run for loops over all the indices.

Any suggestions how this could be achieved?


UPD1

The arrays may be different, as in:

x = np.array([[1, 2, 3], [4, 5, 6]])
y = np.array([[7, 8, 9], [0, 1, 2]])
u = np.array([[3, 4, 5], [6, 7, 8]])
v = np.array([[9, 0, 1], [2, 3, 4]])
[[x, y], [u, v]]

They may also be of different shapes, but for that case a simple np.array([[x, y], [u, v]]) constructor works fine


UPD2

I really want a solution that works with arbitrary x, y, u, v shapes, not necessarily all the same.

like image 240
SiLiKhon Avatar asked Mar 02 '18 07:03

SiLiKhon


Video Answer


3 Answers

a = np.empty(shape=(2, 2), dtype=np.object)
a.fill(x)
like image 166
wim Avatar answered Oct 23 '22 07:10

wim


Found a solution myself:

a=np.zeros(shape=(2, 2), dtype=np.object)
a[:] = [[x, x], [x, x]]
like image 4
SiLiKhon Avatar answered Oct 23 '22 07:10

SiLiKhon


Here is a pretty general method: It works with nested lists, lists of lists of arrays - regardless of whether the shapes of these arrays are different or equal. It also works when the data come clumped together in one single array, which is in fact the trickiest case. (Other methods posted so far will not work in this case.)

Let's start with the difficult case, one big array:

# create example
# pick outer shape and inner shape
>>> osh, ish = (2, 3), (2, 5)
# total shape
>>> tsh = (*osh, *ish)
# make data
>>> data = np.arange(np.prod(tsh)).reshape(tsh)
>>>
# recalculate inner shape to cater for different inner shapes
# this will return the consensus bit of all inner shapes
>>> ish = np.shape(data)[len(osh):]
>>> 
# block them
>>> data_blocked = np.frompyfunc(np.reshape(data, (-1, *ish)).__getitem__, 1, 1)(range(np.prod(osh))).reshape(osh)
>>> 
# admire
>>> data_blocked
array([[array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]]),
        array([[10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]]),
        array([[20, 21, 22, 23, 24],
       [25, 26, 27, 28, 29]])],
       [array([[30, 31, 32, 33, 34],
       [35, 36, 37, 38, 39]]),
        array([[40, 41, 42, 43, 44],
       [45, 46, 47, 48, 49]]),
        array([[50, 51, 52, 53, 54],
       [55, 56, 57, 58, 59]])]], dtype=object)

Using OP's example which is a list of lists of arrays:

>>> x = np.array([[1, 2, 3], [4, 5, 6]])
>>> y = np.array([[7, 8, 9], [0, 1, 2]])
>>> u = np.array([[3, 4, 5], [6, 7, 8]])
>>> v = np.array([[9, 0, 1], [2, 3, 4]])
>>> data = [[x, y], [u, v]]
>>> 
>>> osh = (2,2)
>>> ish = np.shape(data)[len(osh):]
>>> 
>>> data_blocked = np.frompyfunc(np.reshape(data, (-1, *ish)).__getitem__, 1, 1)(range(np.prod(osh))).reshape(osh)
>>> data_blocked
array([[array([[1, 2, 3],
       [4, 5, 6]]),
        array([[7, 8, 9],
       [0, 1, 2]])],
       [array([[3, 4, 5],
       [6, 7, 8]]),
        array([[9, 0, 1],
       [2, 3, 4]])]], dtype=object)

And an example with different shape subarrays (note the v.T):

>>> data = [[x, y], [u, v.T]]
>>> 
>>> osh = (2,2)
>>> ish = np.shape(data)[len(osh):]
>>> data_blocked = np.frompyfunc(np.reshape(data, (-1, *ish)).__getitem__, 1, 1)(range(np.prod(osh))).reshape(osh)>>> data_blocked
array([[array([[1, 2, 3],
       [4, 5, 6]]),
        array([[7, 8, 9],
       [0, 1, 2]])],
       [array([[3, 4, 5],
       [6, 7, 8]]),
        array([[9, 2],
       [0, 3],
       [1, 4]])]], dtype=object)
like image 3
Paul Panzer Avatar answered Oct 23 '22 06:10

Paul Panzer