-1

I have a list of numbers in a string separated by space x="1 2 3 4 5 6 7 8 9 10 11 ..."
I want to extract 3x3 matrices (list of list) from this string so the above string should produce the output = [ [[1,2,3],[4,5,6],[7,8,9]],[ [10,11,12],[13,14,15],[16,17,18] ]...
I tried using the split function on the variable x and loop over it to build the final output but it gets messy. Is there a simple way to do it in simple python or using some library?
We can assume that the number of elements will be consistent with splitting it into 3x3 and the numbers are separated by single space

nicku
  • 279
  • 2
  • 6

5 Answers5

0

With NymPy, this is quite easy.

First, use str.split() to get a list of the numbers, cast them to ints (or floats if you need), and then reshape the array:

import numpy as np

s = '0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17'

a = np.array([int(x) for x in s.split()]).reshape((-1,3))

yields

array([[ 0,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8],
       [ 9, 10, 11],
       [12, 13, 14],
       [15, 16, 17]])

while

a = np.array([int(x) for x in s.split()]).reshape((3,-1))

yields

array([[ 0,  1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10, 11],
       [12, 13, 14, 15, 16, 17]])

And if you know both dimensions of the results, pass them explicitly to reshape() instead of my -1 (which means that one dimension is left unspecified).

joanis
  • 10,635
  • 14
  • 30
  • 40
0

Taking the chunk-implementation from this answer, you can just apply it twice to get 3x3 matrixes:

from itertools import zip_longest

def chunk(source, n):
    return zip_longest(*([iter(source)] * n))

string = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18"
matrix = list(chunk(chunk(string.split(" "), 3), 3))
print(matrix)
treuss
  • 1,913
  • 1
  • 15
0
x = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18"
x_arr = [int(el) for el in x.split(" ")]

def foo(arr, n):
    return [arr[i:(i + n)] for i in range(0, len(arr), n)]

[foo(el, 3) for el in foo(x_arr, 9)]
# [[[1, 2, 3], [4, 5, 6], [7, 8, 9]], [[10, 11, 12], [13, 14, 15], [16, 17, 18]]]
d.b
  • 32,245
  • 6
  • 36
  • 77
0

There's probably a library that is designed to easily do this.

Using base python with numpy:

  1. Parse the string into sets of 3 or insert a semi-colon after every third element.
  2. Use numpy's matrix operation, np.matrix() on each set of three.
  3. Use a control structure to only operate on 3 sets of elements at a time.
MisterJT
  • 412
  • 4
  • 15
0

You can divide your vector in chunks of the right size and use numpy's reshape:

vector = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18"
n = 3
matrix_size = 3*3

vector = np.array([int(x) for x in vector.split()])

matrixes = [vector[i-matrix_size:i].reshape((n,n)) for i in range(matrix_size,len(vector)+1,matrix_size)]

matrixes

[array([[1, 2, 3],
        [4, 5, 6],
        [7, 8, 9]]),
        array([[10, 11, 12],
        [13, 14, 15],
        [16, 17, 18]])]
Ignatius Reilly
  • 1,594
  • 2
  • 6
  • 15