Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何基于每行不同的开始和停止索引有效地索引numpy数组_Python_Numpy_Indexing - Fatal编程技术网

Python 如何基于每行不同的开始和停止索引有效地索引numpy数组

Python 如何基于每行不同的开始和停止索引有效地索引numpy数组,python,numpy,indexing,Python,Numpy,Indexing,我有一个2D numpy数组,其中的行是一个特征的时间序列,基于它我正在训练一个神经网络。为了概括起见,我想在随机点对这些时间序列进行子集划分。我希望它们也有一个最小子集长度。但是,网络需要固定长度的时间序列,因此我需要用零预先填充生成的子集 目前,我正在使用下面的代码,其中包括一个讨厌的for循环,因为我不知道如何使用奇特的索引来解决这个特殊问题。由于这段代码是网络数据生成器的一部分,因此它需要快速跟上需要数据的GPU的步伐。有人知道没有for循环的简单方法吗 import numpy as

我有一个2D numpy数组,其中的行是一个特征的时间序列,基于它我正在训练一个神经网络。为了概括起见,我想在随机点对这些时间序列进行子集划分。我希望它们也有一个最小子集长度。但是,网络需要固定长度的时间序列,因此我需要用零预先填充生成的子集

目前,我正在使用下面的代码,其中包括一个讨厌的for循环,因为我不知道如何使用奇特的索引来解决这个特殊问题。由于这段代码是网络数据生成器的一部分,因此它需要快速跟上需要数据的GPU的步伐。有人知道没有for循环的简单方法吗

import numpy as np
import matplotlib.pyplot as plt

# Amount of time series to consider
batchsize = 25

# Original length of the time series
timesteps = 150

# As an example, fill the 2D array with sine function time series
sinefunction = np.expand_dims(np.sin(np.arange(timesteps)), axis=0)
originalarray = np.repeat(sinefunction, batchsize, axis=0)

# Now the real thing, we want:
# - to start the time series at a random moment (between 0 and maxstart)
# - to end the time series at a random moment
# - however with a minimum length of the resulting subset time series (minlength)
maxstart = 50
minlength = 75

# get random starts
randomstarts = np.random.choice(np.arange(0, maxstart), size=batchsize)

# get random stops
randomstops = np.random.choice(np.arange(maxstart + minlength, timesteps), size=batchsize)

# determine the resulting random sizes of the subset time series
randomsizes = randomstops - randomstarts

# finally create a new 2D array with all the randomly subset time series, however pre-padded with zeros
# THIS IS THE FOR LOOP WE SHOULD TRY TO AVOID
cutarray = np.zeros_like(originalarray)
for i in range(batchsize):
    cutarray[i, -randomsizes[i]:] = originalarray[i, randomstarts[i]:randomstops[i]]
要显示函数的输入和输出,请执行以下操作:

# Show that it worked
f, ax = plt.subplots(2, 1)
ax[0].imshow(originalarray)
ax[0].set_title('original array')
ax[1].imshow(cutarray)
ax[1].set_title('zero-padded subset array')
方法1:基于视图的方法

我们可以利用based将滑动窗口视图转换为零填充版本的输入,并将其分配到零填充版本的输出。由于不规则的性质,矢量化解决方案需要所有这些填充。有利的一面是,处理视图可以提高内存和性能

实现看起来像这样-

from skimage.util.shape import view_as_windows

n = randomsizes.max()
max_extent = randomstarts.max()+n
padlen = max_extent - origalarray.shape[1]
p = np.zeros((origalarray.shape[0],padlen),dtype=origalarray.dtype)
a = np.hstack((origalarray,p))
w = view_as_windows(a,(1,n))[...,0,:]
out_vals = w[np.arange(len(randomstarts)),randomstarts]

out_starts = origalarray.shape[1]-randomsizes    
out_extensions_max = out_starts.max()+n

out = np.zeros((origalarray.shape[0],out_extensions_max),dtype=origalarray.dtype)
w2 = view_as_windows(out,(1,n))[...,0,:]
w2[np.arange(len(out_starts)),out_starts] = out_vals
cutarray_out = out[:,:origalarray.shape[1]]
方法#2:使用
掩蔽

cutarray_out = np.zeros_like(origalarray)
r = np.arange(origalarray.shape[1])
m = (randomstarts[:,None]<=r) & (randomstops[:,None]>r)
s = origalarray.shape[1]-randomsizes
m2 = s[:,None]<=r
cutarray_out[m2] = origalarray[m]
cutarray\u out=np.zero\u like(origalarray)
r=np.arange(Origarray.shape[1])
m=(随机开始[:,无]r)
s=origalarray.形状[1]-随机大小

m2=s[:,None]像一个符咒一样有效!特别是你的第二种方法非常优雅。非常感谢你的灵感!