Увеличьте размер массива, заполнив значения между предыдущими значениями - PullRequest
0 голосов
/ 26 ноября 2018

У меня есть массив размером 19. Я хочу увеличить его размер до 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)

ВМ - это массив размером 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.        ]

Для заполнения new_array:

Если мы рассмотрим первые два элемента массива индекса 0.05263158 0.10526316, все значения массива index30 между этими двумя значениями,их соответствующие местоположения в new_array должны быть заполнены значением массива VM, которое соответствует расположению значения 0.05263158 в индексном массиве и так далее.Я могу использовать для циклов, чтобы сделать это, но я ищу более эффективный способ сделать это?.

Ввод:

[ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

Ожидаемый вывод:

[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]

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Вы можете использовать логическую маску, чтобы определить, где значение из старого массива можно вставить в новый.Это быстрее, чем цикл for, создавая корреляционную матрицу с np.newaxis в индексе и затем np.argwhere(mask), чтобы получить отображение из старого массива в новый.

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)

Вывод этого кодаэто

[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]

, где первое число является неинициализированным значением из пустого массива.

Обратите внимание, что вы не можете получить карту индекса полностью, просто выполнив

index_map = np.argwhere(np.logical_and(
    index[np.newaxis, :-1] <= index30[:, np.newaxis],
    index[np.newaxis, 1:] > index30[:, np.newaxis]
))

так как он пропустит последнюю запись.Поскольку два аргумента в np.logical_and должны иметь одинаковые размеры, нам нужен второй оператор для манипуляции маской.

0 голосов
/ 26 ноября 2018

РЕДАКТИРОВАТЬ: Вы можете использовать np.piecewise.С помощью np.less_equal и np.outer для создания condlist и np.append a nan до VM для создания значений funclist, таких как:

new_array = np.piecewise( x = index30, 
                          condlist = np.less_equal.outer(indexVM, index30), 
                          funclist = np.append(VM,np.nan))

Если выжелая использовать pandas, вы делаете reindex по методу '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.])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...