4

I am working with python 3.7 and I would like to get all the odd columns of a matrix.

To give a example, I have a 4x4 matrix of this style right now.

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

That is...

0 9 1 6
0 3 1 5
0 2 1 7
0 6 1 2

And I would like to get:

9 6
3 5
2 7
6 2

The numbers and the size of the matrix will change but the structure will always be

[[0, (int), 1, (int), 2...], [0, (int), 1, (int), 2 ...], [0, (int), 1, (int), 2...], [0, (int), 1, (int), 2...], ...]

To get the rows I can do [:: 2], but that wonderful solution does not work for me right now. I try to access the matrix with:

for i in matrix:
    for j in matrix:

But none of this doesn't work either. How can I solve it?

Thank you.

sacuL
  • 49,704
  • 8
  • 81
  • 106
Andrew
  • 121
  • 6

2 Answers2

6

Without using numpy, you can use something similar to your indexing scheme ([1::2]) in a list comprehension:

>>> [i[1::2] for i in mat]
[[9, 6], [3, 5], [2, 7], [6, 2]]

Using numpy, you can do something similar:

>>> import numpy as np
>>> np.array(mat)[:,1::2]
array([[9, 6],
       [3, 5],
       [2, 7],
       [6, 2]])
sacuL
  • 49,704
  • 8
  • 81
  • 106
0

If you can't use NumPy for whatever reason, write a custom implementation:

def getColumns(matrix, columns):
    return {c: [matrix[r][c] for r in range(len(matrix))] for c in columns}

It takes a 2D array and a list of columns, and it returns a dictionary where the column indexes are keys and the actual columns are values. Note that if you passed all indices you would get a transposed matrix. In your case,

M = [[0, 9, 1, 6],
    [0, 3, 1, 5],
    [0, 2, 1, 7], 
    [0, 6, 1, 2]]

All odd columns are even indices (because the index of the first one is 0), Therefore:

L = list(range(0, len(M[0]), 2))

And then you would do:

myColumns = getColumns(M, L)
print(list(myColumns.values()))
#result: [[0, 0, 0, 0], [1, 1, 1, 1]]

But since you showed the values as if they were in rows:

def f(matrix, columns):
    return [[matrix[row][i] for i in columns] for row in range(len(matrix))]
print(f(M, L))
#result: [[0, 1], [0, 1], [0, 1], [0, 1]]

And I believe that the latter is what you wanted.

Ape Toshi
  • 153
  • 1
  • 10