Chris
Chris

Reputation: 2477

Read flat list into multidimensional array/matrix in python

I have a list of numbers that represent the flattened output of a matrix or array produced by another program, I know the dimensions of the original array and want to read the numbers back into either a list of lists or a NumPy matrix. There could be more than 2 dimensions in the original array.

e.g.

data = [0, 2, 7, 6, 3, 1, 4, 5]
shape = (2,4)
print some_func(data, shape)

Would produce:

[[0,2,7,6], [3,1,4,5]]

Cheers in advance

Upvotes: 12

Views: 64170

Answers (5)

goofology
goofology

Reputation: 974

[list(x) for x in zip(*[iter(data)]*shape[1])]


(found this post searching for how this works)

Upvotes: 0

meerabo shah
meerabo shah

Reputation: 1

Without Numpy we can do as below as well..

l1 = [1,2,3,4,5,6,7,8,9]

def convintomatrix(x):

    sqrt = int(len(x) ** 0.5)
    matrix = []
    while x != []:
        matrix.append(x[:sqrt])
        x = x[sqrt:]
    return matrix

print (convintomatrix(l1))

Upvotes: 0

B.Mr.W.
B.Mr.W.

Reputation: 19648

For those one liners out there:

>>> data = [0, 2, 7, 6, 3, 1, 4, 5]
>>> col = 4  # just grab the number of columns here

>>> [data[i:i+col] for i in range(0, len(data), col)]
[[0, 2, 7, 6],[3, 1, 4, 5]]

>>> # for pretty print, use either np.array or np.asmatrix
>>> np.array([data[i:i+col] for i in range(0, len(data), col)]) 
array([[0, 2, 7, 6],
       [3, 1, 4, 5]])

Upvotes: 6

Vajk Hermecz
Vajk Hermecz

Reputation: 5722

If you dont want to use numpy, there is a simple oneliner for the 2d case:

group = lambda flat, size: [flat[i:i+size] for i in range(0,len(flat), size)]

And can be generalized for multidimensions by adding recursion:

import operator
def shape(flat, dims):
    subdims = dims[1:]
    subsize = reduce(operator.mul, subdims, 1)
    if dims[0]*subsize!=len(flat):
        raise ValueError("Size does not match or invalid")
    if not subdims:
        return flat
    return [shape(flat[i:i+subsize], subdims) for i in range(0,len(flat), subsize)]

Upvotes: 6

Katriel
Katriel

Reputation: 123762

Use numpy.reshape:

>>> import numpy as np
>>> data = np.array( [0, 2, 7, 6, 3, 1, 4, 5] )
>>> shape = ( 2, 4 )
>>> data.reshape( shape )
array([[0, 2, 7, 6],
       [3, 1, 4, 5]])

You can also assign directly to the shape attribute of data if you want to avoid copying it in memory:

>>> data.shape = shape

Upvotes: 25

Related Questions