Reputation: 627
I want to create a new array containing the ratios of another ndarray.
First simple example:
import numpy as np
week = np.full((3, 4), 2, dtype=float)
week[:,2] = 0
week[2,0:2] =0
week[0,3] =0.99
week[1,3] =1.99
week[2,3] =0.89
week
returns
array([[2. , 2. , 0. , 0.99],
[2. , 2. , 0. , 1.99],
[0. , 0. , 0. , 0.89]])
Now I want to calculate a ndarray containing the ratios of week[:,3]
ratio = week[:,3].reshape(1,-1).T/ week[:,3]
returns
array([[1. , 0.497, 1.112],
[2.01 , 1. , 2.236],
[0.899, 0.447, 1. ]])
exactly what I want.
More general case A 5d array where the first 4 dimensions can change
weeks_5d= np.full((1,1,2, 3, 4), 2, dtype=float)
weeks_5d[:,:,:,:,2] = 0
weeks_5d[:,:,0,2,0:2] =0
weeks_5d[:,:,1,1,0:2] =0
weeks_5d[:,:,:,0,3] = 0.99
weeks_5d[:,:,:,1,3] = 1.99
weeks_5d[:,:,:,2,3] = 0.89
weeks_5d
returns
array([[[[[2. , 2. , 0. , 0.99],
[2. , 2. , 0. , 1.99],
[0. , 0. , 0. , 0.89]],
[[2. , 2. , 0. , 0.99],
[0. , 0. , 0. , 1.99],
[2. , 2. , 0. , 0.89]]]]])
Now I want to calculate the same ratio for each ndarray
Transposing the 5darray returns weird results.
What I need is
array([[[[[1. , 0.497, 1.112],
[2.01 , 1. , 2.236],
[0.899, 0.447, 1. ]]],
[[1. , 0.497, 1.112],
[2.01 , 1. , 2.236],
[0.899, 0.447, 1. ]]]]])
Upvotes: 0
Views: 410
Reputation: 3785
I think a loop is your best hope here and there is a slow and a fast way to do it:
def get_ratios(arr):
ni, nj, nk = arr.shape[:3]
last_dim = arr.shape[3]
new_arr = np.zeros(shape=(ni, nj, nk, last_dim, last_dim),
dtype=np.float64)
for i in range(ni):
for j in range(nj):
for k in range(nk):
week = arr[i, j, k]
ratio = week[:, 3].reshape(-1, 1) / week[:, 3]
new_arr[i, j, k] = ratio
return new_arr
get_ratios(weeks_5d)
prints
array([[[[[1. , 0.49748744, 1.11235955],
[2.01010101, 1. , 2.23595506],
[0.8989899 , 0.44723618, 1. ]],
[[1. , 0.49748744, 1.11235955],
[2.01010101, 1. , 2.23595506],
[0.8989899 , 0.44723618, 1. ]]]]])
Obviously looping over arrays in python is slow but that's what numba
was invented for:
from numba import njit
@njit
def get_ratios(arr):
ni, nj, nk = arr.shape[:3]
last_dim = arr.shape[3]
new_arr = np.zeros(shape=(ni, nj, nk, last_dim, last_dim),
dtype=np.float64)
for i in range(ni):
for j in range(nj):
for k in range(nk):
week = arr[i, j, k, :, 3]
for d1 in range(last_dim):
for d2 in range(last_dim):
new_arr[i, j, k, d1, d2] = week[d1] / week[d2]
return new_arr
get_ratios(weeks_5d)
prints
array([[[[[1. , 0.49748744, 1.11235955],
[2.01010101, 1. , 2.23595506],
[0.8989899 , 0.44723618, 1. ]],
[[1. , 0.49748744, 1.11235955],
[2.01010101, 1. , 2.23595506],
[0.8989899 , 0.44723618, 1. ]]]]])
Upvotes: 1