1

I have a 2D Numpy array with 3 columns. It looks something like this array([[0, 20, 1], [1,2,1], ........, [20,1,1]]). It basically is array of list of lists. How can I convert this matrix into array([(0,20,1), (1,2,1), ........., (20,1,1)])? I want the output to be a array of triple. I have been trying to use tuple and map functions described in Convert numpy array to tuple,

R = mydata #my data is sparse matrix of 1's and 0's
#First row
#R[0] = array([0,0,1,1]) #Just a sample
(rows, cols) = np.where(R)
vals = R[rows, cols]
QQ = zip(rows, cols, vals)
QT = tuple(map(tuple, np.array(QQ))) #type of QT is tuple

QTA = np.array(QT) #type is array
#QTA gives an array of lists
#QTA[0] = array([0, 2, 1])
#QTA[1] = array([0, 3, 1])

But the desired output is QTA should be array of tuples i.e QTA = array([(0,2,1), (0,3,1)]).

Community
  • 1
  • 1
Rajendra Kumar
  • 323
  • 1
  • 3
  • 12
  • It's not an array of lists of lists. It just looks like one when you print it. – Fred Foo Oct 29 '14 at 15:39
  • 2
    What does *"had no success"* mean, exactly? Errors (provide full traceback)? Unexpected outputs (provide inputs and expected and actual outputs)? – jonrsharpe Oct 29 '14 at 15:39
  • 1
    your desired output is invalid `QTA = array[(0,2,1), (0,3,1)]`, it should be `QTA = array([(0,2,1), (0,3,1)])`. – Anzel Oct 29 '14 at 16:08
  • Out of curiosity, why do you want a 1-D numpy array of dtype=object with tuple elements? Doesn't seem very useful. – DSM Oct 29 '14 at 16:31

2 Answers2

3

Your 2d array is not a list of lists, but it readily converts to that

a.tolist()

As Jimbo shows, you can convert this to a list of tuples with a comprehension (a map will also work). But when you try to wrap that in an array, you get the 2d array again. That's because np.array tries to create as large a dimensioned array as the data allows. And with sublists (or tuples) all of the same length, that's a 2d array.

To preserve tuples you have switch to a structured array. For example:

a = np.array([[0, 20, 1], [1,2,1]])
a1=np.empty((2,), dtype=object)
a1[:]=[tuple(i) for i in a]
a1
# array([(0, 20, 1), (1, 2, 1)], dtype=object)

Here I create an empty structured array with dtype object, the most general kind. Then I assign values, using a list of tuples, which is the proper data structure for this task.

An alternative dtype is

a1=np.empty((2,), dtype='int,int,int')
....
array([(0, 20, 1), (1, 2, 1)], 
      dtype=[('f0', '<i4'), ('f1', '<i4'), ('f2', '<i4')])

Or in one step: np.array([tuple(i) for i in a], dtype='int,int,int')

a1=np.empty((2,), dtype='(3,)int') produces the 2d array. dt=np.dtype([('f0', '<i4', 3)]) produces

array([([0, 20, 1],), ([1, 2, 1],)], 
      dtype=[('f0', '<i4', (3,))])

which nests 1d arrays in the tuples. So it looks like object or 3 fields is the closest we can get to an array of tuples.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • Good answer! I just struggled with the "empty((2,)" because I didn't know that the 2 was the size, but I'm a beginner – João Raffs Nov 08 '21 at 12:45
1

not the great solution, but this will work:

# take from your sample
>>>a = np.array([[0, 20, 1], [1,2,1], [20,1,1]]) 

# construct an empty array with matching length
>>>b = np.empty((3,), dtype=tuple)

# manually put values into tuple and store in b
>>>for i,n in enumerate(a):
>>>    b[i] = (n[0],n[1],n[2])

>>>b
array([(0, 20, 1), (1, 2, 1), (20, 1, 1)], dtype=object)

>>>type(b)
numpy.ndarray
Anzel
  • 19,825
  • 5
  • 51
  • 52