Doing arithmetic with python array columns - python

If I have an array: A = np.array([[1,2,0],[5,6,0]]). How can I replace the third column with the sum of the first two or some other arithmetic combination of the other columns?
In the example, calculating the third column as the sum of the sum of the first 2 would give: np.array([[1,2,3],[5,6,11]]).
I've tried A[:2] = A[:,0] + A[:,1] and A[:2] = A[:,0].T + A[:,1].T. I've searched for adding columns, but found ways to insert columns.
import numpy as np
A = np.array([[1,2,3],[5,6,7]])
A[:2] = A[:,0] + A[:,1]
In R this is very easy, but I don't see a simple way to do it in Python.

You're almost there:
>>> A[:,2] = A[:,0] + A[:,1]
>>> A
array([[ 1, 2, 3],
[ 5, 6, 11]])
In A[:, k]:
A is the array you're indexing
: as the first index means "all rows"
For instance, A[:, :] means "all rows and all columns"
k as the second index means "kth column"
For instance, A[1, 2] means "element at row 1, column 2"
A[2, :] means "row 2, all its columns"
This can be generalised to any number of dimensions.

slice array and equate to the sum along the row axis.
A[all rows,column 3]= sum of each row in array A
code below
A[:,2]=A.sum(1)
array([[ 1, 2, 3],
[ 5, 6, 11]])

Related

Add repeated elements of array indexed by another array

I have a relatively simple problem that I cannot solve without using loops. It is difficult for me to figure out the correct title for this problem.
Lets say we have two numpy arrays:
array_1 = np.array([[0, 1, 2],
[3, 3, 3],
[3, 3, 4],
[3, 6, 2]])
array_2 = np.array([[0, 0, 0],
[1, 1, 1],
[2, 2, 2],
[3, 3, 3],
[4, 4, 4],
[5, 5, 5],
[6, 6, 6]])
array_1 represents indices of the rows in array_2 that we want to sum. So for example, 4th row in result array should contain summed all rows in array_2 that have same row indices as all 3s in array_1.
It is much easier to understand it in the code:
result = np.empty(array_2.shape)
for i in range(array_1.shape[0]):
for j in range(array_1.shape[1]):
index = array_1[i, j]
result[index] = result[index] + array_2[i]
Result should be:
[[ 0 0 0]
[ 0 0 0]
[ 3 3 3]
[10 10 10]
[ 2 2 2]
[ 0 0 0]
[ 3 3 3]]
I tried to use np.einsum but I need to use both elements in array as indices and also its rows as indices so I'm not sure if np.einsum is the best path here.
This is the problem I have in graphics. array_1 represent indices of vertices for triangles and array_2 represents normals where index of a row corresponds to the index of the vertex
Any time you're adding something from a repeated index, normal ufuncs like np.add don't work out of the box because they only process a repeated fancy index once. Instead, you have to use the unbuffered version, which is np.add.at.
Here, you have a pair of indices: the row in array_1 is the row index into array_2, and the element of array_1 is the row index into the output.
First, construct the indices explicitly as fancy indices. This will make it much simpler to use them:
output_row = array_1.ravel()
input_row = np.repeat(np.arange(array_1.shape[0]), array_1.shape[1]).ravel()
You can apply input_row directly to array_2, but you need add.at to use output_row:
output = np.zeros_like(array_2)
np.add.at(output, output_row, array_2[input_row])
You really only use the first four rows of array_2, so it could be truncated to
array_2 = array2[:array_1.shape[0]]
In that case, you would want to initialize the output as:
output = np.zeros_like(array_2, shape=(output_row.max() + 1, array2.shape[1]))

python column major and row major matrix

how do i get the 1-D index of an element of a matrix?
for example:
b=np.array([1, 2, 3, 4, 5, 6])
c = b.reshape(2,3,order='F')#colmaj
d = b.reshape(2,3)#rowmaj
this is c:
([[1, 3, 5],
[2, 4, 6]])
this is d:
([[1, 2, 3],
[4, 5, 6]])
if i do c[1,2] i get the element 6, and i need to get the index of the 1-D array which would be 5. i can do this mentally but if i have a large matrix and need to select an element at random i won't be able to. i need to write functions to do this for both colmajor and rowmajor matrices.
def linearize_colmajor(i, j, m, n):
"""
Returns the linear index for the `(i, j)` entry of
an `m`-by-`n` matrix stored in column-major order.
"""
Simply scale the row index by the number of columns and add column index for the row-major order. For the col-major order, use number of rows to scale the row-index and add column index again.
Hence, to get the flattened index for rowmaj version -
i*n+j
To get the flattened index for colmaj version -
i+m*j
where :
i = row index
j = col index
m = number of rows in the matrix
n = number of columns in the matrix
Putting into function format -
def linearize(i, j, m, n, order='C'):
if order=='C': # rowmaj
return i*n+j
elif order=='F': # colmaj
return i+m*j
else:
raise Exception("Invalid order value")
Sample run -
In [42]: linearize(i=1, j=1, m=2, n=3, order='C')
Out[42]: 4 # element : 5 in rowmaj array, d
In [43]: linearize(i=1, j=1, m=2, n=3, order='F')
Out[43]: 3 # element : 4 in colmaj array, c
np.ravel_multi_index converts n-d index to a flat one, with the option of specifying order:
In [152]: np.ravel_multi_index((0,2),(2,3),order='C')
Out[152]: 2
In [153]: c[0,2], c.flat[2]
Out[153]: (5, 5)
Application to the order='F' case is a bit trickier:
In [154]: np.ravel_multi_index([0,2],[2,3],order='F')
Out[154]: 4
In [155]: d[0,2], d.flat[4], d.ravel(order='F')[4]
Out[155]: (3, 5, 3)
In [156]: d.ravel()
Out[156]: array([1, 2, 3, 4, 5, 6])
In [157]: d.ravel(order='F')
Out[157]: array([1, 4, 2, 5, 3, 6])
The [1,2] element is the same in both orders, the last '6'.
Comparison with #Divakar's example:
In [160]: np.ravel_multi_index([1,1],[2,3],order='C')
Out[160]: 4
In [161]: np.ravel_multi_index([1,1],[2,3],order='F')
Out[161]: 3

python - Adding combinations of adjacent rows in a matrix

This is my first post here and I'm a python beginner - all help is appreciated!
I'm trying to add all combinations of adjacent rows in a numpy matrix. i.e. row 1 + row 2, row 2 + row 3, row 3 + row 4, etc... with output to a list
I will then look for the smallest of these outputs and select that item in the list to be printed
I believe I need to use a for loop of some sort but I really am a novice...
Just iterate over the length of the array - 1 and add the pairs as you go into a new list. Then, select the one you want. For example:
>>> x = np.array([[1,2,3], [4,5,6], [7,8,9]])
>>> print [x[i] + x[i+1] for i in range(len(x)-1)]
[array([5, 7, 9]), array([11, 13, 15])]
Suppose you have this
import numpy as np
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7 , 8, 9]])
You can first calculate the sum of each row by using np.sum(arr, axis=1) the argument axis=1 allows to sum each column entries for each line.
In this case, sums = np.sum(arr, axis=1) = array([ 6, 15, 24]).
Then you can iterate over this tab to add the different sums :
lst_sums = []
for s in range(len(sums)-1) :
lst_sums.append(sums[i]+sums[i+1])
Then you can sorted or getting the np.min(sums)
If you need more details you can look at numpy function docs, same for the lists

python, how to select element from each column of matrix

I need to extract one element from each column of a matrix according to an index vector. Say:
index = [0,1,1]
matrix = [[1,4,7],[2,5,8],[3,6,9]]
Index vector tells me I need the first element from column 1, second element from column 2, and third element from column 3.
The output should be [1,5,8]. How can I write it out without explicit loop?
Thanks
You can use advanced indexing:
index = np.array([0,1,2])
matrix = np.array([[1,4,7],[2,5,8],[3,6,9]])
res = matrix[np.arange(matrix.shape[0]), index]
# array([1, 5, 9])
For your second example, reverse your indices:
index = np.array([0,1,1])
matrix = np.array([[1,4,7],[2,5,8],[3,6,9]])
res = matrix[index, np.arange(matrix.shape[1])]
# array([1, 5, 8])
Since you're working with 2-dimensional matrices, I'd suggest using numpy. Then, in your case, you can just use np.diag:
>>> import numpy as np
>>> matrix = np.array([[1,4,7],[2,5,8],[3,6,9]])
>>> matrix
array([[1, 4, 7],
[2, 5, 8],
[3, 6, 9]])
>>> np.diag(matrix)
array([1, 5, 9])
However, #jpp's solution is more generalizable. My solution is useful in your case because you really just want the diagonal of your matrix.
val = [matrix[i][index[i]] for i in range(0, len(index))]

How to multiply a given row `i` or column `j` with a scalar?

import numpy as np
M = np.matrix([
[-1,-2,-3],
[-4,-5,-6]
])
print(M)
How to multiply a given row i or column j with a scalar?
How to acces a given column or row as a list?
How to set a given column or row, given a list (of the appropiate length)?
To multiply a particular column:
M[:,colnumber] *= scalar
Or a row:
M[rownumber,:] *= scalar
And of course, accessing them as an iterable is the same thing:
col_1 = M[:,1]
Although, that gives you a new matrix, not a list. Although, honestly, I can't quite seem to figure out all of these operations with matrix objects -- And these don't really seem like matrix type operations. Is there a reason that you're using matrix instead of array objects? If you want matrix multiplication, you can always use np.dot(array_mat1, array_mat2)
You can use slicing to accomplish this:
>>> M = np.matrix([
... [-1,-2,-3],
... [-4,-5,-6]
... ])
>>> M[1,:] *= 2 # multiply all elements in second row by 2
>>> M
matrix([[ -1, -2, -3],
[ -8, -10, -12]])
>>> M[:,1] *= 2 # multiply all elements in second column by 2
>>> M
matrix([[ -1, -4, -3],
[ -8, -20, -12]])
To assign a given column or row to a list:
>>> M[:,1] = [[0], [0]] # note the nested lists to reassign column
>>> M
matrix([[ -1, 0, -3],
[ -8, 0, -12]])
>>> M[1,:] = [2, 2, 2] # flat list to reassign row
>>> M
matrix([[-1, 0, -3],
[ 2, 2, 2]])
Using Python 2.7
1) You can multiply a row or a column by some scalar s like this:
M[i, :] *= s
M[:, j] *= s
2) You can access a row or column like this:
M[i, :]
M[:, j]
3) You can set a row or column to a list l like this:
M[i, :] = l
M[:, j] = l
Note that in the last one, your list (if you are setting a column) would have to be a list within a list (i.e. the outer list acts as a row, the inner lists act as columns).

Categories

Resources