简体   繁体   中英

How to divide one columns value by a previous rows column(not the same column) and add the result as a new dimension to a numpy array?

What I want to do is take a numpy array like this:

[[1, 2,  4, 7,  9, 15,  0],
 [3, 4,  3, 5, 10,  2, -2],
 [5, 6, 56, 7, 20,  1,  2]]

I want to take each rows last column and divide that by the previous row's 4th column and take the result and add it to the array as a new dimension the output I want should look like this

[[1, 2,  4, 7,  9, 15,  0,  0],
 [3, 4,  3, 5, 10,  2, -2, -.2857],
 [5, 6, 56, 7, 20,  1,  2, .4]]

Can this be done without a for loop? (Ok I guess it's not efficient to do this without a for loop) But I'm still not sure how to do it with one either

import numpy as np
myarray = np.array([[1,2,4,7,9,15,0.0], [3, 4,3,5,10,2,-2], [5,6,56,7,20,1,2]])
#the division:
column_divs = myarray[:,-1][1:] / myarray[:,3][:-1]
#adds a 'placeholder' zero value, as the first element:
column_divs = np.hstack(([0], column_divs))
#adds the required column to the end of the array:
print np.hstack((myarray, column_divs.reshape(-1,1)))
#output:
[[  1.      2.       4.       7.       9.      15.      0.       0.        ]
 [  3.      4.       3.       5.      10.       2.     -2.      -0.28571429]
 [  5.      6.      56.       7.      20.       1.      2.      0.4        ]]
import numpy as np
lis=[[1, 2,  4, 7,  9, 15,  0],
 [3, 4,  3, 5, 10,  2, -2],
 [5, 6, 56, 7, 20,  1,  2]]
new_lis=[lis[i][:]+[lis[i][-1]/lis[i][3]] for i in range(len(lis))]
nparray=np.matrix(new_lis)

You'll want to use np.concatenate :

np.concatenate((a, np.concatenate(([[0]], a[1:, [-1]] / a[:-1, [3]].astype(float)))), axis=1)

The astype(float) is required for Python 2.x if your array has int dtype.

This can be also written with hstack and vstack :

np.hstack((a, np.vstack(([[0]], a[1:, [-1]] / a[:-1, [3]].astype(float)))))

Instead of slicing the rows, it may be OK to use roll :

np.hstack((a, np.vstack((a[:, [-1]] / np.roll(a[:, [3]], 1).astype(float)))))

Apologies in advance for the non-answer, but unless you're prioritizing algorithmic purity over performance, you definitely want to do this with a for loop or similar construct.

There's probably a way to accomplish this purely with matrix operations (multiply the original by a custom kernel and concatenate the result as a new column on the original matrix) but it won't be as efficient. Consider that Strassen's algorithm (an example of efficient multiplication of two square matrices) is O(n^log7) , or ~ O(n^2.807) where n is the size of the matrices being multiplied in terms of number of elements. A for loop would be O(m) , where m is the number of rows in the matrix in question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM