How do you extract a column from a multi-dimensional array? - python

Does anybody know how to extract a column from a multi-dimensional array in Python?

>>> import numpy as np
>>> A = np.array([[1,2,3,4],[5,6,7,8]])
>>> A
array([[1, 2, 3, 4],
[5, 6, 7, 8]])
>>> A[:,2] # returns the third columm
array([3, 7])
See also: "numpy.arange" and "reshape" to allocate memory
Example: (Allocating a array with shaping of matrix (3x4))
nrows = 3
ncols = 4
my_array = numpy.arange(nrows*ncols, dtype='double')
my_array = my_array.reshape(nrows, ncols)

Could it be that you're using a NumPy array? Python has the array module, but that does not support multi-dimensional arrays. Normal Python lists are single-dimensional too.
However, if you have a simple two-dimensional list like this:
A = [[1,2,3,4],
[5,6,7,8]]
then you can extract a column like this:
def column(matrix, i):
return [row[i] for row in matrix]
Extracting the second column (index 1):
>>> column(A, 1)
[2, 6]
Or alternatively, simply:
>>> [row[1] for row in A]
[2, 6]

If you have an array like
a = [[1, 2], [2, 3], [3, 4]]
Then you extract the first column like that:
[row[0] for row in a]
So the result looks like this:
[1, 2, 3]

check it out!
a = [[1, 2], [2, 3], [3, 4]]
a2 = zip(*a)
a2[0]
it is the same thing as above except somehow it is neater
the zip does the work but requires single arrays as arguments, the *a syntax unpacks the multidimensional array into single array arguments

>>> x = arange(20).reshape(4,5)
>>> x array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]])
if you want the second column you can use
>>> x[:, 1]
array([ 1, 6, 11, 16])

If you have a two-dimensional array in Python (not numpy), you can extract all the columns like so,
data = [
['a', 1, 2],
['b', 3, 4],
['c', 5, 6]
]
columns = list(zip(*data))
print("column[0] = {}".format(columns[0]))
print("column[1] = {}".format(columns[1]))
print("column[2] = {}".format(columns[2]))
Executing this code will yield,
>>> print("column[0] = {}".format(columns[0]))
column[0] = ('a', 'b', 'c')
>>> print("column[1] = {}".format(columns[1]))
column[1] = (1, 3, 5)
>>> print("column[2] = {}".format(columns[2]))
column[2] = (2, 4, 6)

def get_col(arr, col):
return map(lambda x : x[col], arr)
a = [[1,2,3,4], [5,6,7,8], [9,10,11,12],[13,14,15,16]]
print get_col(a, 3)
map function in Python is another way to go.

array = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
col1 = [val[1] for val in array]
col2 = [val[2] for val in array]
col3 = [val[3] for val in array]
col4 = [val[4] for val in array]
print(col1)
print(col2)
print(col3)
print(col4)
Output:
[1, 5, 9, 13]
[2, 6, 10, 14]
[3, 7, 11, 15]
[4, 8, 12, 16]

[matrix[i][column] for i in range(len(matrix))]

The itemgetter operator can help too, if you like map-reduce style python, rather than list comprehensions, for a little variety!
# tested in 2.4
from operator import itemgetter
def column(matrix,i):
f = itemgetter(i)
return map(f,matrix)
M = [range(x,x+5) for x in range(10)]
assert column(M,1) == range(1,11)

You can use this as well:
values = np.array([[1,2,3],[4,5,6]])
values[...,0] # first column
#[1,4]
Note: This is not working for built-in array and not aligned (e.g. np.array([[1,2,3],[4,5,6,7]]) )

let's say we have n X m matrix(n rows and m columns) say 5 rows and 4 columns
matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16],[17,18,19,20]]
To extract the columns in python, we can use list comprehension like this
[ [row[i] for row in matrix] for in range(4) ]
You can replace 4 by whatever number of columns your matrix has.
The result is
[ [1,5,9,13,17],[2,10,14,18],[3,7,11,15,19],[4,8,12,16,20] ]

I think you want to extract a column from an array such as an array below
import numpy as np
A = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
Now if you want to get the third column in the format
D=array[[3],
[7],
[11]]
Then you need to first make the array a matrix
B=np.asmatrix(A)
C=B[:,2]
D=asarray(C)
And now you can do element wise calculations much like you would do in excel.

One more way using matrices
>>> from numpy import matrix
>>> a = [ [1,2,3],[4,5,6],[7,8,9] ]
>>> matrix(a).transpose()[1].getA()[0]
array([2, 5, 8])
>>> matrix(a).transpose()[0].getA()[0]
array([1, 4, 7])

Just use transpose(), then you can get the columns as easy as you get rows
matrix=np.array(originalMatrix).transpose()
print matrix[NumberOfColumns]

Well a 'bit' late ...
In case performance matters and your data is shaped rectangular, you might also store it in one dimension and access the columns by regular slicing e.g. ...
A = [[1,2,3,4],[5,6,7,8]] #< assume this 4x2-matrix
B = reduce( operator.add, A ) #< get it one-dimensional
def column1d( matrix, dimX, colIdx ):
return matrix[colIdx::dimX]
def row1d( matrix, dimX, rowIdx ):
return matrix[rowIdx:rowIdx+dimX]
>>> column1d( B, 4, 1 )
[2, 6]
>>> row1d( B, 4, 1 )
[2, 3, 4, 5]
The neat thing is this is really fast. However, negative indexes don't work here! So you can't access the last column or row by index -1.
If you need negative indexing you can tune the accessor-functions a bit, e.g.
def column1d( matrix, dimX, colIdx ):
return matrix[colIdx % dimX::dimX]
def row1d( matrix, dimX, dimY, rowIdx ):
rowIdx = (rowIdx % dimY) * dimX
return matrix[rowIdx:rowIdx+dimX]

If you want to grab more than just one column just use slice:
a = np.array([[1, 2, 3],[4, 5, 6],[7, 8, 9]])
print(a[:, [1, 2]])
[[2 3]
[5 6]
[8 9]]

Despite using zip(*iterable) to transpose a nested list, you can also use the following if the nested lists vary in length:
map(None, *[(1,2,3,), (4,5,), (6,)])
results in:
[(1, 4, 6), (2, 5, None), (3, None, None)]
The first column is thus:
map(None, *[(1,2,3,), (4,5,), (6,)])[0]
#>(1, 4, 6)

I prefer the next hint:
having the matrix named matrix_a and use column_number, for example:
import numpy as np
matrix_a = np.array([[1,2,3,4],[5,6,7,8],[9,10,11,12]])
column_number=2
# you can get the row from transposed matrix - it will be a column:
col=matrix_a.transpose()[column_number]

All columns from a matrix into a new list:
N = len(matrix)
column_list = [ [matrix[row][column] for row in range(N)] for column in range(N) ]

Related

How to add value to particular part of python list?

NOTE: My need isn't this e.g. List[2:4] = 5
Suppose my List=[1,2,3,4,5,6]
I want to add 5 from index 2 to 4.
So the resultant List would be like List=[1,2,8,9,10,6]
If I have 2d array List=[[1,2,3],[4,5,6]] and want to add 5 to col 1 List=[[6,2,3],[9,5,6]]then what would be the code?
One approach is
my_list = [1,2,3,4,5]
add_item = [2,3]
new_list = [x+1 if i in add_item else x for i, x in enumerate(my_list)]
print(new_list)
This can be easily done through list comprehension.
The following function takes a 2D array 2d, a position index i and a value v, and adds v to the i-th element of each array.
def add_value(2d, i, v):
return [array[:i] + [array[i]+v] + array[i+1:] for array in 2d]
So, calling the function on the list in your example:
my_list = [[1,2,3],[4,5,6]]
add_value(my_list,0,5)
Would print out the desired output:
>>> [[6, 2, 3], [9, 5, 6]]
Numpy arrays can handle such slice operations:
import numpy as np
List = np.array([1, 2, 3, 4, 5, 6])
List[2:5] += 5
print(List)
Numpy will really come in handy for you if you have many of such tasks to do in your code. However, if it's just a one time thing in your code, you can do:
List = [1, 2, 3, 4, 5, 6]
for i in range(2, 5):
List[i] += 5
print(List)
Output:
[1, 2, 8, 9, 10, 6]
EDIT
Addressing your edit, you can also use numpy arrays like so:
import numpy as np
List = np.array([[1, 2, 3], [4, 5, 6]])
List[0] += 5
print(List)
Or using a loop:
List = [[1, 2, 3], [4, 5, 6]]
for i in range(len(List[0])):
List[0][i] += 5
print(List)
Output:
[[6, 7, 8], [4, 5, 6]]
One solution uses NumPy but my implementation is on an in-built list and other solutions are copying unnecessary elements.
So here I found the manual way to do it.
List = [[1,2,3,4,5],[6,7,8,9,10]]
# for horizontal update
colToUpdate = 2
for r in range(0,2):
A[r][colToUpdate] += add
# for vertical update
rowToUpdate = 1
for c in range(2,5):
A[rowToUpdate][c] += add

functions on arrays of different sizes in for loop

I have two arrays of different sizes that I want to perform logical functions on in a for loop. For example, if I have:
array1 = [6,7,8]
array2 = [1,2,3,4,5]
I want to do each element from array1 minus each element of array2 to get something like
[6-1,6-2,6-3,6-4,6-5],[7-1,7-2,7-3,7-4,7-5],[8-1,8-2,8-3,8-4,8-5]
which is subtracting each element from array2 from each element of array1
So i tried to do a for loop like:
for i in range(len(array1)):
ar = array1[i]-array2
and also
for i in range(len(array1)):
for j in range(len(array2)):
ar = array1[i]-array2[j]
But neither of these seem to be working
The first way seems to be returning an array of the right shape but certainly not the right values.
I'd like it to be returned in separate arrays because in reality, I have a very large sample size.
We can solve this using itertools.product
from itertools import product
from operator import sub
final = []
for item in array1:
prods = product([item], array2)
subs = [sub(*p) for p in prods]
final.append(subs)
print(final)
# [[5, 4, 3, 2, 1], [6, 5, 4, 3, 2], [7, 6, 5, 4, 3]]
How it works is product returns the cartesian product of the two arrays in the form of tuples, so:
(6, 1), (6, 2), etc....
Then we simply apply the sub function to each tuple using a list-comprehension.
The following solution should work using a list comprehension:
result = []
for value1 in array1:
result.append([value1 - value2 for value2 in array2])
You could even write this in 1 line using both for loops for the list comprehension:
result = [[value1 - value2 for value2 in array2] for value1 in array1]
Loops solution:
array1 = [6, 7, 8]
array2 = [1, 2, 3, 4, 5]
arr = []
for i in array1:
tmp = []
for j in array2:
tmp.append(i - j)
arr.append(tmp)
print(arr)
Output:
[[5, 4, 3, 2, 1], [6, 5, 4, 3, 2], [7, 6, 5, 4, 3]]
Your for loop is nearly correct except, you overwrite the value of ar every iteration (and you make it slightly more complicated with range)
You can achieve this through list comprehension
[[i - j for j in array2] for i in array1]
# [[5, 4, 3, 2, 1], [6, 5, 4, 3, 2], [7, 6, 5, 4, 3]]
You were on the right track but you had your arrays switched. You want array1 inside the inner loop to perform the operation you want to perform:
array1 = [6,7,8]
array2 = [1,2,3,4,5]
finalarray=[]
for i in range(len(array2)):
for j in range(len(array1)):
ar = array1[j]-array2[i]
finalarray.append(ar)
print(finalarray)
>>>[5, 6, 7, 4, 5, 6, 3, 4, 5, 2, 3, 4, 1, 2, 3]
ar is not being treated properly in your code, it needs to be an array of arrays (matrix) and you'll need another variable to hold the result per iteration, there's probably a better way to do this using list comprehensions but here is one way:
array1 = [6,7,8]
array2 = [1,2,3,4,5]
ar = []
row = []
for i in range(len(array1)):
for j in range(len(array2)):
row.append(array1[i]-array2[j])
ar.append(row)
row = []
print ar
There are plenty of good answers here, but another option especially useful for larger arrays is to use numpy, a package designed for moving large arrays of numbers efficiently. One possible answer in numpy would be this:
import numpy as np
array1 = np.arange(6,9) # make arrays 1 and 2
array2 = np.arange(1,6)
output = (array1.repeat(array2.shape[0]) # repeat array1 as many times as there are elements in array2
.reshape(array1.shape[0], -1) # reshape so we have a row for each element in array1
) - array2 # subtract array2 from each row
output
array([[5, 4, 3, 2, 1],
[6, 5, 4, 3, 2],
[7, 6, 5, 4, 3]])

sum columns of part of 2D array Python

INPUT:
M = [[1,2,3],
[1,2,3],
[1,2,3]]
how take the sum of the columns in the two first rows and implement it in the array M
OUTPUT:
M = [[2,4,6],
[1,2,3]]
Use numpy.add.reduceat:
import numpy as np
M = [[1,2,3],
[1,2,3],
[1,2,3]]
np.add.reduceat(M, [0, 2])
# indices [0,2] splits the list into [0,1] and [2] to add them separately,
# you can see help(np.add.reduceat) for more
# array([[2, 4, 6],
# [1, 2, 3]])
M = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
M[:2] = [[a + b for a, b in zip(M[0], M[1])]]
print(M) # [[5, 7, 9], [7, 8, 9]]
Things to google to understand this:
M[:2] =: python slice assignment
[... for .. in ...]: python list comprehension
for a, b in ...: python tuple unpacking loop

Python revert accumulated matrix

I have a matrix like this
[[1,2,4,6],
[4,7,9,9],
[1,9,10,20]]
how i get the partial sums by columns in python?
[[1,2,4,6],
[(4-1),(7-2),(9-4),(9-6)],
[(1-4),(9-7),(10-9),(20-9)]]
If you want a solution that doesn't involve numpy, and just uses list of lists and itertools.tee (which is builtin), then the below should work
from itertools import tee
a = [[1,2,4,6],
[4,7,9,9],
[1,9,10,20]]
b = []
b.append(a[0])
# Create two iterators and advance one once.
x, y = tee(a)
next(y)
# Iterate over your two iterators and construct a list t which is their difference
# then append this list to b
for i, j in zip(x, y):
t = [h-g for g, h in zip(i,j)]
b.append(t)
print(b)
# [[1, 2, 4, 6],
# [3, 5, 5, 3],
# [-3, 2, 1, 11]]
Try
np.vstack((Z[0],np.diff(Z,axis=0)))
where Z is the matrix you are differentiating.
From the second line, what you want is just the difference of row i and row i-1, and the first line is just the first line of the original array. The easiest way to get this is with numpy. So this works:
In [1]: import numpy as np
In [2]: a = np.array( [[1,2,4,6],
...: [4,7,9,9],
...: [1,9,10,20]]
...: )
In [3]: np.vstack( (a[0], a[1:]-a[:-1]) )
Out[3]:
array([[ 1, 2, 4, 6],
[ 3, 5, 5, 3],
[-3, 2, 1, 11]])
As Lord Henry Wotton (!) points out, the difference a[1:]-a[:-1] is the same as np.diff(a, axis=0).
If you don't want to use numpy or itertools, here is the code
>>> a=[[1,2,4,6],
... [4,7,9,9],
... [1,9,10,20]]
>>> a_r = a[::-1] # reverse original list
>>> for i in range(len(a_r)-1):
... for j in range(len(a_r[0])):
... a_r[i][j] = a_r[i][j] - a_r[i+1][j]
...
>>> a=a_r[::-1] # reverse result
>>> for i in a: print i
[1, 2, 4, 6]
[3, 5, 5, 3]
[-3, 2, 1, 11]
I think this one is nice
>>> a = [[1,2,4,6],
... [4,7,9,9],
... [1,9,10,20]]
>>> c = [[0]*5] ; c.extend(a)
>>> print [[ s-r for r, s in zip(*t)] for t in zip(c[:-1],c[1:])]
[[1, 2, 4, 6], [3, 5, 5, 3], [-3, 2, 1, 11]]
>>>
Here I prepend a list of zeros to the list of lists (obtaining c), and by a bit of packing and unpacking using zip I have a list of lists with the expected results.

Looping through a mutidimentional array in python

How do i achieve line 9 and 10 i.e the two for loops in python
matrix = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
]
newMatrix = []
for (i=0; i < len(matrix); i++):
for (j=0; j < len(matrix[i]); j++):
newMatrix[j][i] = matrix[i][j]
print newMatrix
PS: i know i can do [[row[i] for row in matrix] for i in range(4)] but how i do only using for loops
Use range (or xrange).
for i in range(len(matrix)):
for j in range(len(matrix[i])):
FYI, assigning to newMatrix[i][j] will fail, because newMatrix is an empty list. You need to add a new empty list to newMatrix for every row and then append the new value to that list in every iteration.
You can use the enumerate() function to loop over both the matrix values and give you indices:
newMatrix = [[0] * len(matrix) for _ in xrange(len(matrix[0]))]
for i, row in enumerate(matrix):
for j, value in enumerate(row):
newMatrix[j][i] = value
This outputs:
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
Because you are addressing rows and columns in the new matrix directly, you need to have initialized that new matrix with empty values first. The list comprehension on the first line of my example does this for you. It creates a new matrix that is (y, x) in size, given an input matrix of size (x, y).
Alternatively, you can avoid explicit looping altogether by (ab)using the zip function:
newMatrix = zip(*matrix)
which takes each row of matrix and groups each column in those rows into new rows.
In the generic case, python for constructs loop over sequences. The range() and xrange() functions can produce numerical sequences for you, these generate a number sequence in much the same way that a for loop in C or JavaScript would produce:
>>> for i in range(5):
>>> print i,
0 1 2 3 4
but the construct is far more powerful than the C-style for construct. In most such loops your goal is to provide indices into some sequence, the python construct bypasses the indices and goes straight to the values in the sequence instead.
Just to throw something else into the mix of answers, if you are doing any kind of matrix operations with Python, consider using numpy:
>>> import numpy
>>> matrix = numpy.matrix([
... [1, 2, 3, 4],
... [5, 6, 7, 8],
... [9, 10, 11, 12]
... ])
The transpose is pretty simple to do:
>>> matrix.transpose()
matrix([[ 1, 5, 9],
[ 2, 6, 10],
[ 3, 7, 11],
[ 4, 8, 12]])
If I understand you correctly, what you want to do is a matrix transposition, which can be done this way:
zip(*matrix)

Categories

Resources