#python #numpy
Вопрос:
У меня есть массив данных, которые я хочу отобрать, чтобы быстрее выполнить анализ первого порядка. Если я хочу исследовать по одной точке за раз, я могу сделать это с помощью нарезки:
import numpy as np
array = np.arange(0,20000)
samplespace = 5000
sampledarray = array[::samplespace]
Однако мне нужно проанализировать регионы по нескольким элементам в целом. Единственный способ, которым я могу это сделать,-это использовать цикл for:
import numpy as np
array = np.arange(0,20000)
samplespace = 5000
n = 3
sampledarray = array[0::samplespace]
for i in range(1,n):
arraysample_i = array[i::samplespace]
indices = np.linspace(i,len(sampledarray),len(arraysample_i)).astype(int)
sampledarray = np.insert(sampledarray,indices,arraysample_i)
print(sampledarray)
>>> [ 0 1 2 5000 5001 5002 10000 10001 10002 15000 15001 15002 ]
Я беспокоюсь о том, что цикл занимает много времени, если я выполняю его с большим массивом и выполняю выборку в нескольких измерениях. Есть ли более простой и быстрый способ сделать это?
Ответ №1:
import numpy as np
import itertools
array = np.arange(0,20000)
samplespace = 5000
indices = itertools.chain.from_iterable((ind for ind in range(i, len(array), samplespace) )for i in range(n))
output = array[list(indices)]
выход:
array([ 0, 5000, 10000, 15000, 1, 5001, 10001, 15001, 2,
5002, 10002, 15002])
Ответ №2:
Спасибо aminrd за предложение использовать itertools; это пакет, который я раньше не использовал, но в итоге дал мне то, что мне было нужно.
Вот что я в итоге сделал:
import numpy as np
import itertools
array = np.arange(0,20000)
samplespace = 5000
n = 3
iterate = itertools.count(start=0,step=samplespace)
num = int(len(array)/samplespace)
idx = np.array([next(iterate) for _ in range(num)])
idxlist = np.zeros(0)
for i in range(n):
idxi = np.copy(idx) i
idxlist = np.append(idxlist,idxi)
idxlist = np.sort(idxlist).astype(int)
sampledarray = array[idxlist]
print(sampledarray)
>>> [ 0 1 2 5000 5001 5002 10000 10001 10002 15000 15001 15002 ]
Это позволило мне довольно легко расширить его на большее количество измерений, и вместо того, чтобы работать с моим большим набором данных, мне нужно было только манипулировать массивом индексов:
import numpy as np
import itertools
array = np.empty((200,200),dtype=object)
# I know this is a lousy way to define the array but it works well for illustrative purposes
for i in range(200):
for j in range(200):
array[i,j] = (i,j)
samplespace = 50
n = 3
iteratex = itertools.count(start=0,step=samplespace)
iteratey = itertools.count(start=0,step=samplespace)
num = int(len(array)/samplespace)
idxx = np.array([next(iteratex) for _ in range(num)])
idxy = np.array([next(iteratey) for _ in range(num)])
idxlistx = np.zeros(0)
idxlisty = np.zeros(0)
for i in range(n):
idxxi = np.copy(idxx) i
idxyi = np.copy(idxy) i
idxlistx = np.append(idxlistx,idxxi)
idxlisty = np.append(idxlisty,idxyi)
idxlistx = np.sort(idxlistx).astype(int)
idxlisty = np.sort(idxlisty).astype(int)
# Having to index the array twice seems awkward, even though I understand it is necessary
# for array broadcasting if the two index arrays are of different lengths
sampledarray = array[idxlistx,:]
sampledarray = sampledarray[:,idxlisty]
print(sampledarray)
>>>[[(0, 0) (0, 1) (0, 2) (0, 50) (0, 51) (0, 52) (0, 100) (0, 101) (0, 102)
(0, 150) (0, 151) (0, 152)]
[(1, 0) (1, 1) (1, 2) (1, 50) (1, 51) (1, 52) (1, 100) (1, 101) (1, 102)
(1, 150) (1, 151) (1, 152)]
[(2, 0) (2, 1) (2, 2) (2, 50) (2, 51) (2, 52) (2, 100) (2, 101) (2, 102)
(2, 150) (2, 151) (2, 152)]
[(50, 0) (50, 1) (50, 2) (50, 50) (50, 51) (50, 52) (50, 100) (50, 101)
(50, 102) (50, 150) (50, 151) (50, 152)]
[(51, 0) (51, 1) (51, 2) (51, 50) (51, 51) (51, 52) (51, 100) (51, 101)
(51, 102) (51, 150) (51, 151) (51, 152)]
[(52, 0) (52, 1) (52, 2) (52, 50) (52, 51) (52, 52) (52, 100) (52, 101)
(52, 102) (52, 150) (52, 151) (52, 152)]
[(100, 0) (100, 1) (100, 2) (100, 50) (100, 51) (100, 52) (100, 100)
(100, 101) (100, 102) (100, 150) (100, 151) (100, 152)]
[(101, 0) (101, 1) (101, 2) (101, 50) (101, 51) (101, 52) (101, 100)
(101, 101) (101, 102) (101, 150) (101, 151) (101, 152)]
[(102, 0) (102, 1) (102, 2) (102, 50) (102, 51) (102, 52) (102, 100)
(102, 101) (102, 102) (102, 150) (102, 151) (102, 152)]
[(150, 0) (150, 1) (150, 2) (150, 50) (150, 51) (150, 52) (150, 100)
(150, 101) (150, 102) (150, 150) (150, 151) (150, 152)]
[(151, 0) (151, 1) (151, 2) (151, 50) (151, 51) (151, 52) (151, 100)
(151, 101) (151, 102) (151, 150) (151, 151) (151, 152)]
[(152, 0) (152, 1) (152, 2) (152, 50) (152, 51) (152, 52) (152, 100)
(152, 101) (152, 102) (152, 150) (152, 151) (152, 152)]]
Ответ №3:
import numpy as np
array = np.arange(0,20000)
samplespace = 5000
n = 3
sampledarray = np.stack([array[i::samplespace] for i in range(n)]).flatten(order='F')
выход:
array([ 0, 1, 2, 5000, 5001, 5002, 10000, 10001, 10002,
15000, 15001, 15002])