Using for loop:
X = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
def submatrix(X, i, j):
X=X[:]
del(X[i]) # delete the row
for n in range(len(X)):
del(X[n][j]) # delete the column elements of the rows
return X
X_new = submatrix(X, 1, 1)
[[1, 3], [7, 9]]
Answer from seralouk on Stack OverflowUsing for loop:
X = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
def submatrix(X, i, j):
X=X[:]
del(X[i]) # delete the row
for n in range(len(X)):
del(X[n][j]) # delete the column elements of the rows
return X
X_new = submatrix(X, 1, 1)
[[1, 3], [7, 9]]
How's this?
def submatrix(X, i, j):
return [[elem for x, elem in enumerate(row) if x != i]
for y, row in enumerate(X) if y != j]
X = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
print(submatrix(X, 1, 1))
In [74]: [row[2:5] for row in LoL[1:4]]
Out[74]: [[2, 3, 4], [2, 3, 4], [2, 3, 4]]
You could also mimic NumPy's syntax by defining a subclass of list:
class LoL(list):
def __init__(self, *args):
list.__init__(self, *args)
def __getitem__(self, item):
try:
return list.__getitem__(self, item)
except TypeError:
rows, cols = item
return [row[cols] for row in self[rows]]
lol = LoL([list(range(10)) for i in range(10)])
print(lol[1:4, 2:5])
also yields
[[2, 3, 4], [2, 3, 4], [2, 3, 4]]
Using the LoL subclass won't win any speed tests:
In [85]: %timeit [row[2:5] for row in x[1:4]]
1000000 loops, best of 3: 538 ns per loop
In [82]: %timeit lol[1:4, 2:5]
100000 loops, best of 3: 3.07 us per loop
but speed isn't everything -- sometimes readability is more important.
For one, you can use slice objects directly, which helps a bit with both the readability and performance:
r = slice(1,4)
s = slice(2,5)
[LoL[i][s] for i in range(len(LoL))[r]]
And if you just iterate over the list-of-lists directly, you can write that as:
[row[s] for row in LoL[r]]
python - How to extract all K*K submatrix of matrix with or without NumPy? - Stack Overflow
How to go over submatrices of a matrix - and fast?
matrices - A function to extract a submatrix from a matrix - TeX - LaTeX Stack Exchange
python - Numpy extract submatrix - Stack Overflow
Your code is working ( with change of order of vars and constants ):
for j in range(len(M3)-2):
for i in range(len(M3[0])-2):
X_i_j = [row[0+i:3+i] for row in M3[0+j:3+j]]
print('=======')
for x in X_i_j:
print(x)
I would solve it slightly different. a function to read y-number-of-rows then a function to read x-number-of-columns from those rows, which then is your sub.
This would work for any (2D) array / sub-array
Sample:
def read_y_rows(array, rows, offset):
return array[offset:rows + offset]
def read_x_cols(array, cols, offset):
return list(row[offset:cols + offset] for row in array)
def get_sub_arrays(array, x_dim_cols, y_dim_rows):
"""
get 2D sub arrays by x_dim columns and y_dim rows
from 2D array (list of lists)
"""
result = []
for start_row in range(len(array) - y_dim_rows + 1):
y_rows = read_y_rows(array, y_dim_rows, start_row)
for start_col in range(len(max(array, key=len)) - x_dim_cols + 1):
x_columns = read_x_cols(y_rows, x_dim_cols, start_col)
result.append(x_columns)
return result
to use it you could do:
M3 = [list(range(5)) for i in range(6)]
sub_arrays = get_sub_arrays(M3, 3, 3) ## this would also work for 2x2 arrays
the sub_arrays is again a list of lists, containing all found subarrays, you could print them like this:
for sub_array in sub_arrays:
print()
for row in sub_array:
print(row)
I know it is a lot more code than above, just wanted to share this code.
r=int(input())
c=int(input())
n=min(r,c)
k=3
matrix=[list(map(str,input().split())) for i in range(r)]
t = []
a=[]
for i in range(0,r,k):
for j in range(0,c,k):
t.append([matrix[i+ii][j+jj] for ii in range(k) for jj in range(k)])
print(t)
In for loop you used n variable in range. so it will end in the minimum of row and col .That's why you got error..Thank you
If your matrix size is fixed and is divisible by 3 something like this would do the trick:
for i in range(3):
for j in range(3):
print(M[i:i+3,j:j+3])
It also works for bigger matrices but it will leave unused elements if it can't index three elements.
Basically I am indexing the matrix M in both axis. For mor info, please, check Numpy docs
Hi,
I have an MxN matrix (list of lists), where each element is a tuple of 2 ints.
Given a rectangle size PxQ, where P<=M, Q<=N), I need to find the submatrix inside the MxN matrix which, when calculating the sum of the second element of each tuple inside the rectangle, returns the highest result which is not larger than a number B. Each submatrix is defined by its upper-left corner.
For example, the MxN matrix can be:
[ [(1, 2), (1, 1), (0, 3), (4, 0)],
[(10, 10), (5, 7), (1, 3), (9, 2)],
[(0, 0), (1, 9), (0, 0), (1, 1)] ]
and the rectangle size can be 2x3, so there are 4 submatrices to go over:
[(1, 2), (1, 1), (0, 3)
(10, 10), (5, 7), (1, 3)]
[(1, 1), (0, 3), (4, 0)
(5, 7), (1, 3), (9, 2)]
[(10, 10), (5, 7), (1, 3)
(0, 0), (1, 9), (0, 0)]
[(5, 7), (1, 3), (9, 2)
(1, 9), (0, 0), (1, 1)]
If B=27, the correct submatrix, in this case, is the second one, since it has the highest sum of 2nd elements, which is 2+1+3+10+7+3=26, which is smaller than B. The third submatrix yields a larger sum (29) but 29 > 27 so it is not the right answer.
I'm looking for an efficient way to go over the submatrices and determine if the sum of the 2nd elements is the largest. Is there a faster way than using for loops?
I made some commands to store a matrix and to show the matrix, an element of the matrix, or a submatrix.
The elements of the matrix are saved <matrix name>-<y>-<x>, so you could define further commands with that.
Result

Code
\documentclass{article}
\usepackage{etoolbox}
\usepackage{pgffor}
\usepackage{booktabs}
\def\dmname{}
\newcounter{dmx}
\newcounter{dmy}
\newcommand{\dmlines}[1]{%
\setcounter{dmx}{0}
\forcsvlist{\dmelements}{#1}
\stepcounter{dmy}
}
\newcommand{\dmelements}[1]{%
\csdef{\dmname-\thedmy-\thedmx}{#1}%
\stepcounter{dmx}%
}
\newcommand{\definematrix}[2]{%
% #1 = name
% #2 = matrix
\gdef\dmname{#1}%
\setcounter{dmy}{0}%
\forcsvlist{\dmlines}{#2}%
\csxdef{\dmname-w}{\thedmx}%
\csxdef{\dmname-h}{\thedmy}%
}
\newcommand{\getmatrixelement}[3]{%
% #1 = name
% #2 = y
% #3 = x
\csuse{#1-#2-#3}%
}
\newcommand{\getsubmatrix}[5]{%
% #1 = name
% #2 = y
% #3 = x
% #4 = y2
% #5 = x2
\def\dmtablecontent{}%
\foreach \y in {#2, ..., #4} {%
\foreach \x in {#3, ..., #5} {%
\xappto\dmtablecontent{\csuse{#1-\y-\x}}%
\ifnumless{\x}{#5}{%
\xappto\dmtablecontent{&}%
}{}%
}%
\xappto\dmtablecontent{\\}%
}%
%
\begin{tabular}{*{\the\numexpr#5-#3+1\relax}{c}}%
\dmtablecontent%
\end{tabular}%
}
\newcommand{\getmatrixwidth}[1]{%
% #1 = name
\csuse{#1-w}%
}
\newcommand{\getmatrixheight}[1]{%
% #1 = name
\csuse{#1-h}%
}
\newcommand{\getmatrix}[1]{%
% #1 = name
\getsubmatrix{#1}{0}{0}
{\the\numexpr\getmatrixheight{#1}-1\relax}
{\the\numexpr\getmatrixwidth{#1}-1\relax}%
}
\newcommand{\getmatrixwithoutrc}[3]{%
% shows the matrix without the given row and column
% #1 = name
% #2 = row
% #3 = column
\def\dmtablecontent{}%
\def\dmymax{\the\numexpr\getmatrixheight{#1}-1\relax}%
\def\dmxmax{\the\numexpr\getmatrixwidth{#1}-1\relax}%
\foreach \y in {0, ..., \dmymax} {%
\ifnumequal{\y}{#2}{}{%
\foreach \x in {0, ..., \dmxmax} {%
\ifnumequal{\x}{#3}{}{%
\xappto\dmtablecontent{\csuse{#1-\y-\x}}%
\ifnumless{\x}{\dmxmax}{%
\xappto\dmtablecontent{&}%
}{}%
}%
}%
\xappto\dmtablecontent{\\}%
}%
}%
%
\begin{tabular}{*{\getmatrixwidth{#1}}{c}}
\dmtablecontent
\end{tabular}
}
\begin{document}
\definematrix{a}{{1, 2}, {3, 4}}
\definematrix{b}{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
\renewcommand{\arraystretch}{1.5}
\begin{tabular}{ll}
\toprule
\textbf{Result} & \textbf{Command}\\
\midrule
& \verb|\definematrix{a}{{1, 2}, {3, 4}}|\\
& \verb|\definematrix{b}{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}| \\
$\getmatrixheight{a} \times \getmatrixwidth{a}$ &
\verb|$\getmatrixheight{a} \times \getmatrixwidth{a}$|
\\
\getmatrix{a} &
\verb|\getmatrix{a}|
\\
\getmatrixelement{a}{0}{0} &
\verb|\getmatrixelement{a}{0}{0}|
\\
\getmatrixelement{a}{1}{0} &
\verb|\getmatrixelement{a}{1}{0}|
\\
\getsubmatrix{a}{0}{1}{1}{1} &
\verb|\getsubmatrix{a}{0}{1}{1}{1}|
\\
\getmatrix{b} &
\verb|\getmatrix{b}|
\\
\getsubmatrix{b}{1}{1}{2}{2} &
\verb|\getsubmatrix{b}{1}{1}{2}{2}|
\\
\getmatrixwithoutrc{b}{1}{1} &
\verb|\getmatrixwithoutrc{b}{1}{1}|
\\
\bottomrule
\end{tabular}
\end{document}
Here's a sagetex solution using SAGE, a computer algebra system (CAS). Documentation on some matrix basics is here. The complete documentation for matrices is available in PDF form here. With 685 pages of documentation you'll find SAGE can do most anything you want.
\documentclass{article}
\usepackage{sagetex,amsmath,amsfonts}
\linespread{2.0}
\begin{document}
\begin{sagesilent}
latex.matrix_delimiters(left='[', right=']')
A=matrix([[5,0,0],[0,2,-5],[6,1,-2]])
B = matrix(4,[0..15])
C= B.delete_rows([0,3]).delete_columns([1,2])
D= A.delete_rows([0]).delete_columns([0])
\end{sagesilent}
Consider the matrices below: \[A=\sage{A} \hspace{2cm} B=\sage{B}\]
The entry $A_{1,1}=\sage{A[0][0]}$ because SAGE is Python
based and indices start with $0$. We can create submatrices $C=\sage{C}$ and $D=\sage{D}$ by
deleting rows and columns. SAGE can calculate $C \cdot D = \sage{C*D}$ and its determinant:
\begin{sagesilent}
latex.matrix_delimiters(left='|', right='|')
\end{sagesilent}
$det(C \cdot D)=\sage{C*D}=\sage{det(C*D)}$
\end{document}
The result, running in Cocalc:

The most important thing to remember is that SAGE, which is Python based and gives you access to Python, has a default starting index of 0. So removing the first row and column from your matrix is given by: D= A.delete_rows([0]).delete_columns([0]). What surrounds your matrix in LaTeX are the delimiters, documentation for changing them in SAGE is here. The code latex.matrix_delimiters(left='|', right='|') changed the delimiters so I could show the determinant in LaTeX.
SAGE is not part of LaTeX. The easiest way to get started is with a free Cocalc account.
Give np.ix_ a try:
Y[np.ix_([0,3],[0,3])]
This returns your desired result:
In [25]: Y = np.arange(16).reshape(4,4)
In [26]: Y[np.ix_([0,3],[0,3])]
Out[26]:
array([[ 0, 3],
[12, 15]])
One solution is to index the rows/columns by slicing/striding. Here's an example where you are extracting every third column/row from the first to last columns (i.e. the first and fourth columns)
In [1]: import numpy as np
In [2]: Y = np.arange(16).reshape(4, 4)
In [3]: Y[0:4:3, 0:4:3]
Out[1]: array([[ 0, 3],
[12, 15]])
This gives you the output you were looking for.
For more info, check out this page on indexing in NumPy.
Your inverse operation can be split into 2 simplier operation:
- concatenate rows(
numpy.vstack) - concatenate columns(
numpy.hstack)
So, if you have matrix divided into 4 submatrix:
M = |m1|m2|
|m3|m4|
then M = hstack(vstack(m1, m2), vstack(m3, m4).
This operations can be code like this:
import itertools
import math
# iterators
def ihstack(*matrixes):
return map(lambda rows: itertools.chain(*rows), zip(*matrixes))
def ivstack(*matrixes):
return itertools.chain(*matrixes)
# main function
def squarejoin(*matrixes):
size = int(math.sqrt(len(matrixes)))
assert size ** 2 == len(matrixes), 'Incorrect number of matrices'
return _matrixjoin(matrixes, size, size)
def _matrixjoin(matrixes, hsize, vsize):
print(matrixes, hsize, vsize)
return ivstack(*(ihstack(*itertools.islice(matrixes, i*hsize, (i+1)*hsize)) for i in range(vsize)))
Here I have an example program where a 2 loops implementation works and is crystal clear in its intent, a 1 loop implementation works and is, imho, slightly less clear and eventually a 0 (explicit, btw) loops implementation that, alas, is buggy.
My vote goes to the two loops... further, I'd like to be shown what's wrong with my 0 loops attempt
Code
import itertools
def pm(m):
for row in m: print row
mat = []
n = 8
for i in range(n):
mat.append(range(i*n, i*n+n))
# this is shorthand for your splitmat function
res = map(lambda (x,y):
map(lambda z:z[y[0]:y[1]],mat[x[0]:x[1]]),
itertools.product([(0,n/2),(n/2,n)],repeat=2))
pm(res)
print "\n2 cycles"
mat = []
for i, j in ((0,1),(2,3)):
for a, b in zip(res[i],res[j]):
mat.append(a+b)
pm(mat)
print "\n1 cycle"
mat = []
for i, j in ((0,1),(2,3)):
map(lambda x: mat.append(x[0]+x[1]), zip(res[i],res[j]))
pm(mat)
print "\n0 cycles"
mat = map(lambda i_j:
map(lambda x: x[0]+x[1], zip(res[i_j[0]],res[i_j[1]])), ((0,1),(2,3)))
pm(mat)
Output
[[0, 1, 2, 3], [8, 9, 10, 11], [16, 17, 18, 19], [24, 25, 26, 27]]
[[4, 5, 6, 7], [12, 13, 14, 15], [20, 21, 22, 23], [28, 29, 30, 31]]
[[32, 33, 34, 35], [40, 41, 42, 43], [48, 49, 50, 51], [56, 57, 58, 59]]
[[36, 37, 38, 39], [44, 45, 46, 47], [52, 53, 54, 55], [60, 61, 62, 63]]
2 cicli
[0, 1, 2, 3, 4, 5, 6, 7]
[8, 9, 10, 11, 12, 13, 14, 15]
[16, 17, 18, 19, 20, 21, 22, 23]
[24, 25, 26, 27, 28, 29, 30, 31]
[32, 33, 34, 35, 36, 37, 38, 39]
[40, 41, 42, 43, 44, 45, 46, 47]
[48, 49, 50, 51, 52, 53, 54, 55]
[56, 57, 58, 59, 60, 61, 62, 63]
1 ciclo
[0, 1, 2, 3, 4, 5, 6, 7]
[8, 9, 10, 11, 12, 13, 14, 15]
[16, 17, 18, 19, 20, 21, 22, 23]
[24, 25, 26, 27, 28, 29, 30, 31]
[32, 33, 34, 35, 36, 37, 38, 39]
[40, 41, 42, 43, 44, 45, 46, 47]
[48, 49, 50, 51, 52, 53, 54, 55]
[56, 57, 58, 59, 60, 61, 62, 63]
0 cicli
[[0, 1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 12, 13, 14, 15], [16, 17, 18, 19, 20, 21, 22, 23], [24, 25, 26, 27, 28, 29, 30, 31]]
[[32, 33, 34, 35, 36, 37, 38, 39], [40, 41, 42, 43, 44, 45, 46, 47], [48, 49, 50, 51, 52, 53, 54, 55], [56, 57, 58, 59, 60, 61, 62, 63]]