Reputation: 4353
I have a matrix, say:
A = [1, 2, 3]
[4, 5, 6]
[7, 8, 9]
and I want to construct another matrix, having two extra rows as such
B = [1, 2, 3]
[2.5, 3.5, 4.5]
[4, 5, 6]
[5.5, 6.5, 7.5]
[7, 8, 9]
where every element on the second and fourth row is the average of the elements above and below it.
I want to do this, in python, numpy, for an n x m matrix.
EDIT: The generalization to this would be to insert the means of two neighboring rows every n rows. For example
A = [ 1, 2, 3]
[ 4, 5, 6]
[ 7, 8, 9]
[10, 11, 12]
[13, 14, 15]
[16, 17, 18]
[19, 20, 21]
and , for n = 3 , B would become
B = [ 1, 2, 3]
[ 4, 5, 6]
[ 7, 8, 9]
[8.5, 9.5, 10.5]
[10, 11, 12]
[13, 14, 15]
[16, 17, 18]
[17.5, 18.5, 19.5]
[19, 20, 21]
and so on. The AVERAGE layers are still the average of the one above and the one below them. I am looking for a function that would give this for any n.
Upvotes: 2
Views: 129
Reputation: 221614
Here's an approach making use of slicing -
newvals = (A[1:] + A[:-1])/2.0
out = np.empty((A.shape[0]+newvals.shape[0],A.shape[1]))
out[::2] = A
out[1::2] = newvals
Here's another one with np.insert
for a generic case -
np.insert(A.astype(float),range(1,A.shape[0]),newvals,axis=0)
Generalizing to handle every possible n
-
def insert_row_averages(A, n=1):
slice2 = A[n::n]
v = (A[n-1::n][:slice2.shape[0]] + slice2)/2.0
return np.insert(A.astype(float),n*np.arange(1,v.shape[0]+1),v,axis=0)
Sample runs -
In [195]: A0
Out[195]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
In [196]: insert_row_averages(A0, n=1)
Out[196]:
array([[ 1. , 2. , 3. ],
[ 2.5, 3.5, 4.5],
[ 4. , 5. , 6. ],
[ 5.5, 6.5, 7.5],
[ 7. , 8. , 9. ]])
In [197]: A
Out[197]:
array([[ 1, 2, 3],
[ 4, 5, 6],
[ 7, 8, 9],
[10, 11, 12],
[13, 14, 15],
[16, 17, 18],
[19, 20, 21]])
In [198]: insert_row_averages(A, n=3)
Out[198]:
array([[ 1. , 2. , 3. ],
[ 4. , 5. , 6. ],
[ 7. , 8. , 9. ],
[ 8.5, 9.5, 10.5],
[ 10. , 11. , 12. ],
[ 13. , 14. , 15. ],
[ 16. , 17. , 18. ],
[ 17.5, 18.5, 19.5],
[ 19. , 20. , 21. ]])
Upvotes: 4
Reputation: 215047
One option would be to calculate the averages and then insert it back to A
:
np.insert(A.astype(float), [1,2], (A[1:] + A[:-1])/2, axis=0)
#array([[ 1. , 2. , 3. ],
# [ 2.5, 3.5, 4.5],
# [ 4. , 5. , 6. ],
# [ 5.5, 6.5, 7.5],
# [ 7. , 8. , 9. ]])
Upvotes: 1