0

I have numpy matrices collected in the list. I need to built an array which contains particular entry from each matrix, for example second entry from each matrix. I would like to avoid loop.

The data is already in this shape, I don't want to change the structure or change matrices into something else.

Example code - data structure:

L = []
m1 = np.mat([ 1, 2, 3]).T
m2 = np.mat([ 4, 5, 6]).T
m3 = np.mat([ 7, 8, 9]).T
m4 = np.mat([10,11,12]).T
m5 = np.mat([13,14,15]).T  
L.append(m1)
L.append(m2)
L.append(m3)
L.append(m4)
L.append(m5)

The only way I managed to do it is through the loop:

S = []
for k in range(len(L)):
    S.append(L[k][1,0])
print 'S = %s' % S

the output I need: S = [2, 5, 8, 11, 14] I thought something like: S1 = np.array(L[:][1,0]) should work but whatever I try I have the error like: TypeError: list indices must be integers, not tuple. What is the efficient way (numpy style) of accessing it?

tomasz74
  • 16,031
  • 10
  • 37
  • 51
  • 1
    If you don't want to change the structure, I think you're out of luck. You can't use numpy indexing to act on something which isn't a numpy object, and your L is a Python list. – DSM Jul 10 '13 at 12:27

3 Answers3

2

Using list comprehension:

>>> x = [i[1] for i in L]
>>> x
[2, 5, 8, 11, 14]
>>> 
Pawel Miech
  • 7,742
  • 4
  • 36
  • 57
  • Isn't it a bit like writing a loop but in different style? I though more, by accessing by indexing – tomasz74 Jul 10 '13 at 12:18
  • It is a concise and fairly efficient way of creating new lists. List comprehension are typical for Python, they are considered 'pythonic', [here's the discussion about their efficiency](http://stackoverflow.com/questions/1247486/python-list-comprehension-vs-map) – Pawel Miech Jul 10 '13 at 12:27
  • Thanks @Pawelmhm it does speed up the execution, so for sure it is improvement. – tomasz74 Jul 10 '13 at 12:39
2

You could also do

>>> M = np.column_stack([m1,m2,m3,m4,m5])

and then access the rows via

>>> M[1]
matrix([[ 2,  5,  8, 11, 14]])

If you've got larger vectors, and want to access multiple rows, this might be faster in the long run.

Rick
  • 1,784
  • 3
  • 15
  • 25
1

As DSM says, either you should have a 2D matrix and use numpy slicing, otherwise some form of list-comp as shown by Pawelmhm... A faster form will be:

from operator import itemgetter
els = map (itemgetter(1), (m1, m2, m3, m4, m5))
Jon Clements
  • 138,671
  • 33
  • 247
  • 280