Reputation: 581
I have a array of size 19. I want to increase its size to 30(new_array).
size =len(VM)
index = np.linspace(1,size,size)/size
index30 = np.linspace(1,30,30)/30
new_array = np.empty(shape=30)
VM is a array of size 19
index
[0.05263158 0.10526316 0.15789474 0.21052632 0.26315789 0.31578947
0.36842105 0.42105263 0.47368421 0.52631579 0.57894737 0.63157895
0.68421053 0.73684211 0.78947368 0.84210526 0.89473684 0.94736842
1. ]
index30
[0.03333333 0.06666667 0.1 0.13333333 0.16666667 0.2
0.23333333 0.26666667 0.3 0.33333333 0.36666667 0.4
0.43333333 0.46666667 0.5 0.53333333 0.56666667 0.6
0.63333333 0.66666667 0.7 0.73333333 0.76666667 0.8
0.83333333 0.86666667 0.9 0.93333333 0.96666667 1. ]
To fill the new_array:
If we consider first two elements of index array 0.05263158 0.10526316
, all the values of index30 array between these two values, their corresponding locations in the new_array should be filled with the value of VM array that corresponds to location of value 0.05263158
in index array and so on.
I can use for loops to do this but i am looking for more efficient way to do this?.
Input:
[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
expected output:
[nan,1,1,2,3,3,4,5,5,6,6,7,8,8,9,10,10,11,12,12,13,13,14,15,15,16,17,17,18,19]
Upvotes: 1
Views: 347
Reputation: 121
You can use a boolean mask to determine where the value from the old array can be inserted into the new one. This is faster than a for loop by creating a correlation matrix with np.newaxis
in the index and then np.argwhere(mask)
to get the mapping from the old array to the new.
import numpy as np
VM = np.arange(1, 20)
size =len(VM)
index = np.linspace(1,size,size)/size
index30 = np.linspace(1,30,30)/30
new_array = np.empty(30)
mask = index30[:, np.newaxis] >= index[np.newaxis, :]
mask[:,:-1] = np.logical_and(
mask[:,:-1],
index30[:, np.newaxis] < index[np.newaxis, 1:]
)
index_map = np.argwhere(mask)
new_array[index_map[:,0]] = VM[index_map[:,1]]
print(new_array)
The output of this code is
[4607182418800017408 1 1 2 3 3 4 5 5 6 6 7 8 8 9 10 10 11 12 12 13 13 14 15 15 16 17 17 18 19]
where the first number is the uninitialized value from the empty array.
Note that you cannot get the index map completely by simply doing
index_map = np.argwhere(np.logical_and(
index[np.newaxis, :-1] <= index30[:, np.newaxis],
index[np.newaxis, 1:] > index30[:, np.newaxis]
))
as it will omit the last entry. Since two arguments in np.logical_and
have to have the same dimensions we need the second statement for manipulating the mask.
Upvotes: 1
Reputation: 29635
EDIT: You can use np.piecewise
. With np.less_equal
and np.outer
to create the condlist
and np.append
a nan
to VM
to create the values of the funclist
such as:
new_array = np.piecewise( x = index30,
condlist = np.less_equal.outer(indexVM, index30),
funclist = np.append(VM,np.nan))
If you are willing to use pandas
, you do a reindex
with the method 'ffill'
.
import numpy as np
import pandas as pd
VM = np.arange(1,20)
size = len(VM)
indexVM = np.linspace(1,size,size)/size
index30 = np.linspace(1,30,30)/30
new_array = pd.Series(VM, index=indexVM).reindex(index30, method='ffill').values
print (new_array)
array([nan, 1., 1., 2., 3., 3., 4., 5., 5., 6., 6., 7., 8.,
8., 9., 10., 10., 11., 12., 12., 13., 13., 14., 15., 15., 16.,
17., 17., 18., 19.])
Upvotes: 3