J'ai un tableau numpy 1-d de longueur n, et je veux l'étirer à m (n
>>> def stretch(x,to,fill=np.nan):
... step = to/len(x)
... output = np.repeat(fill,to)
... foreign = np.arange(0,to,step).round().astype(int)
... output[foreign] = x
... return output
>>> arr = np.random.rand(6553)
>>> stretch(arr,6622)
File "<ipython-input-216-0202bc39278e>", line 2, in <module>
stretch(arr,6622)
File "<ipython-input-211-177ee8bc10a7>", line 9, in stretch
output[foreign] = x
ValueError: shape mismatch: value array of shape (6553,) could not be broadcast to indexing result of shape (6554,)
4 Réponses :
Vous pouvez utiliser resize pour redimensionner le tableau.
Une fois qu'il est redimensionné, vous pouvez appliquer la logique appropriée pour réorganiser le contenu.
Vérifiez le lien ci-dessous: https://docs.scipy.org/doc/ numpy / reference / generated / numpy.ndarray.resize.html
Le redimensionnement met des zéros à la fin, alors comment vais-je le séparer des autres zéros (possibles)? Quelle est la bonne façon d'utiliser le redimensionnement?
Cette approche place les éléments non-nan aux limites, laissant les valeurs nan au centre, bien qu'elle n'espace pas uniformément les valeurs nan .
In [104]: stretch(arr, stretch_len) Out[104]: array([ 4., 5., 1., nan, nan, 2., 6., 8.]) In [105]: arr = [4, 5, 1, 2, 6, 8, 9] In [106]: stretch(arr, stretch_len) Out[106]: array([ 4., 5., 1., nan, 2., 6., 8., 9.]) In [107]: stretch(arr, 9) Out[107]: array([ 4., 5., 1., nan, nan, 2., 6., 8., 9.])
Voici quelques cas de test que j'ai testés:
arr = [4,5,1,2,6,8]
stretch_len = 8
def stretch(arr, stretch_len):
stretched_arr = np.empty(stretch_len)
stretched_arr.fill(np.nan)
arr_len = len(arr)
if arr_len % 2 == 0:
mid = int(arr_len/2)
stretched_arr[:mid] = arr[:mid]
stretched_arr[-mid:] = arr[-mid:]
else:
mid = int(np.floor(arr_len/2))
stretched_arr[:mid] = arr[:mid]
stretched_arr[-mid-1:] = arr[-mid-1:]
return stretched_arr
Deux nans consécutifs ne satisfont pas à la condition d'être régulièrement espacés. Je m'attendrais à au moins 2 échantillons entre eux.
Utilisation de roundrobin de itertools Recettes :
from itertools import cycle, islice
def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Recipe credited to George Sakkis
pending = len(iterables)
nexts = cycle(iter(it).__next__ for it in iterables)
while pending:
try:
for next in nexts:
yield next()
except StopIteration:
pending -= 1
nexts = cycle(islice(nexts, pending))
def stretch(x, to, fill=np.nan):
n_gaps = to - len(x)
return np.hstack([*roundrobin(np.array_split(x, n_gaps+1), np.repeat(fill, n_gaps))])
arr = [4,5,1,2,6,8]
stretch(arr, 8)
# array([ 4., 5., nan, 1., 2., nan, 6., 8.])
arr2 = np.random.rand(655)
stretched_arr2 = stretch(arr,662)
np.diff(np.argwhere(np.isnan(stretched_arr2)), axis=0)
# nans are evenly spaced
array([[83],
[83],
[83],
[83],
[83],
[83]])
n_gaps : calcule le nombre de lacunes à combler (longueur souhaitée - longueur actuelle)
np_array_split : avec n_gaps + 1 , il divise le tableau d'entrée en la même longueur que possible
roundrobin : puisque np_array_split génère un tableau de plus que les vides, roundrobin-ing (c'est-à-dire alternativement itérer) accorde que np.nan n'est jamais à l'une ou l'autre extrémité du résultat .
Bien que Chris ait résolu le problème, j'ai trouvé une réponse plus courte, qui peut être utile,
>>> aa[:5] array([0.78581616, 0.1630689 , 0.52039993, nan, 0.89844404]) >>> aa[-5:] array([0.7063653 , nan, 0.2022172 , 0.94604503, 0.91201897])
Quelle est la logique derrière l'ajout de NaN? Comment sont-ils positionnés?
«Systématiquement» l'explique, en d'autres termes, régulièrement espacé (autant que possible). Je vais gérer les NaN de différentes manières, ce qui est hors sujet pour cette question.