-3

I have a file which consists of a number of matrices separated by blank line. How can I find the all diagonals of all matrices using NumPy? The matrices are not of fixed size

1 2 3
1 1 1 
2 2 2

3 4 
3 2 
4 2 


3 2 3
4 2 2
abd
  • 73
  • 1
  • 8

1 Answers1

2

Here is a recipe for iterating over a file in chunks delimited by a regex pattern. This is perhaps a bit more powerful than is needed here; the regex pattern is merely '\n{2,}', i.e. two-or-more end-of-line characters. On the other hand, once you have this tool, there is no need to reinvent the wheel.

Once you have a chunk -- a multi-line string representing an array -- you can parse it with np.loadtxt and find all diagonals using the diagonals function:

import io
import re
import numpy as np

# http://stackoverflow.com/q/17508697/190597
def open_chunk(readfunc, delimiter, chunksize=1024):
    """
    readfunc(chunksize) should return a string.
    """
    remainder = ''
    for chunk in iter(lambda: readfunc(chunksize), ''):
        pieces = re.split(delimiter, remainder + chunk)
        for piece in pieces[:-1]:
            yield piece
        remainder = pieces[-1]
    if remainder:
        yield remainder

# Based on http://stackoverflow.com/a/6313407/190597
def diagonals(L):
    h, w = len(L), len(L[0])
    return [[L[h - p + q - 1][q]
             for q in range(max(p-h+1,0), min(p+1, w))]
            for p in range(h + w - 1) ]

with open('data', 'r') as f:
    for chunk in open_chunk(f.read, r'\n{2,}'):
        arr = np.loadtxt(io.BytesIO(chunk))
        print([d for d in diagonals(arr) if len(d) != 1])

yields

[[1.0, 2.0], [1.0, 1.0, 2.0], [2.0, 1.0]]
[[3.0, 2.0], [3.0, 2.0]]
[[3.0, 2.0], [2.0, 2.0]]
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • But i have matrices which are of variable sizes so how can i choose the chunk before blank line as every matrices are separated by a blank line – abd Mar 07 '15 at 19:09
  • The code above works with arrays of variable size. As long as the string-arrays are separated by 2-or-more end-of-line characters, the code above will work. – unutbu Mar 07 '15 at 19:18
  • error in the line of above code arr = np.loadtxt(io.BytesIO(chunk)) cannot convert string to float so i changed it to np.genfromtxt((chunk)) but now i got no diagonals i want to get all diagonals – abd Mar 07 '15 at 19:41
  • Your file must contain non-numeric strings which you did not show in your question above. – unutbu Mar 07 '15 at 19:46
  • It returns me only one diagonal i want all possible diagonals so what can i do? – abd Mar 07 '15 at 20:04
  • For example in above first matrix 1,1,2 || 1,2 || 2,1 are the possible diagonals and i got only one diagonal 1,1,2 – abd Mar 07 '15 at 20:06
  • So others visiting this page will understand your question more clearly, please edit your question to include the expected output. – unutbu Mar 07 '15 at 20:57