Reputation: 947
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
Upvotes: 0
Views: 1887
Reputation: 35269
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 ]]
Upvotes: 2
Reputation: 157374
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)))))
Upvotes: 1
Reputation: 15216
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.
Upvotes: 0
Reputation: 250971
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)
Upvotes: 1