0

I have an array of tuples of tuples where the second level should not be a tuple and I want to convert it all to something like a 2-d array. Is there a quick way to restructure from this messy 1-d to a nice clean 2-d or structured array?

Note: These tuples do contain various types. I would like to be able to transpose and 2-d slice etc.. this data.

ie...

[((1,-4,7.0),)
((2,-5,8.0),)
((3,-6,9.0),)]

Edited to try and accommodate issues people pointed out with the original question

  • Is this how your array really looks? Looks you have tuples and not extra dimensions. – Moses Koledoye Sep 23 '16 at 14:25
  • Sorry Yes this is the structure the print statement spits out. I suppose it is an array of tuples of tuples? AKA there is no fancy way to convert this? – user2463977 Sep 23 '16 at 14:32
  • What's the shape and dtype? – hpaulj Sep 23 '16 at 14:48
  • Is that really *exactly* what is printed out? I.e. did you copy-and-paste that into stackoverflow? Numpy arrays do not capitalize the name `array` in their string representation. – Warren Weckesser Sep 23 '16 at 14:57
  • Ah! Yes thank you - this particular example happens to be shape : (2271824L,) (so one dimension) but they dtype is very complex. I suppose this points me to the answer - 'it's complicated'. Thank you! – user2463977 Sep 23 '16 at 14:58
  • To warren: No I added the 'Array' which was silly. I will remove it. The formatting was otherwise copied as the actual content is complex. I see now that that was a poor choice. – user2463977 Sep 23 '16 at 15:00

2 Answers2

0

You can use np.squeeze

np.squeeze(<your array>)

S. C
  • 156
  • 3
0

The dtype is important here. The closest I can come to your display is with a nested dtype

In [182]: dt1=np.dtype('i,i,f')
In [183]: dt=np.dtype([('a',dt1,),('b',dt1,),('c',dt1,)])

In [184]: x=np.ones(1,dtype=dt)

In [185]: print(x)
[((1, 1, 1.0), (1, 1, 1.0), (1, 1, 1.0))]

(no final ,)

If I use the repr rather than print's default str, I see the dtype as well:

In [186]: print(repr(x))
array([((1, 1, 1.0), (1, 1, 1.0), (1, 1, 1.0))], 
      dtype=[('a', [('f0', '<i4'), ('f1', '<i4'), ('f2', '<f4')]), ('b', [('f0', '<i4'), ('f1', '<i4'), ('f2', '<f4')]), ('c', [('f0', '<i4'), ('f1', '<i4'), ('f2', '<f4')])])

Reshape or squeeze does not work here because it is already 1d. view or astype can work. Do you want to just flatten the dtype, or make it all float? What kind of shape do you expect? Currently each record consists of 9 numbers.

With a compatible dtype I can view this array as a record of 9 values:

In [195]: dt2=np.dtype('i,i,f,i,i,f,i,i,f')
In [196]: x.view(dt2)
Out[196]: 
array([(1, 1, 1.0, 1, 1, 1.0, 1, 1, 1.0)], 
      dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<f4'), ('f3', '<i4'), ('f4', '<i4'), ('f5', '<f4'), ('f6', '<i4'), ('f7', '<i4'), ('f8', '<f4')])

The simplest way to turn this x into an array of floats is with tolist (it's not fastest):

In [256]: x['c']=(20,21,22)
In [257]: x['b']=(10,11,12)
In [258]: x['a']=(1,2,3)

In [263]: print(x)
[((1, 2, 3.0), (10, 11, 12.0), (20, 21, 22.0))]
In [264]: np.array(x.tolist())
Out[264]: 
array([[[  1.,   2.,   3.],
        [ 10.,  11.,  12.],
        [ 20.,  21.,  22.]]])
hpaulj
  • 221,503
  • 14
  • 230
  • 353