2
votes

Comment diviser un tableau numpy basé sur un contenu de tuple?

Disons que j'ai un tableau [0, 1, 2, 3, 4, 5, 6, 7] et un tuple: (3, 3, 2) .

Je cherche un moyen de diviser mon tableau en un tableau 3 basé sur mes données de tuple:

[0, 1, 2]
[3, 4, 5]
[6, 7]

Je peux écrire un code simple comme celui-ci pour obtenir ce que je veux, mais je cherche une manière correcte et pythonique de faire ceci:

J'ai utilisé des listes pour plus de simplicité.

a = [0, 1, 2, 3, 4, 5, 6, 7]
b = (3, 3, 2)
pointer = 0
for i in b:
        lst = a[pointer:pointer+i]
        pointer += i
        print(lst)

Ou celui-ci:

a = [0, 1, 2, 3, 4, 5, 6, 7]
b = (3, 3, 2)

pointer = 0
for i in b:
        lst = []
        for j in range(i):
                lst.append(a[pointer])
                pointer += 1
        print(lst)

Résultats:

[0, 1, 2]
[3, 4, 5]
[6, 7]


2 commentaires

C'est généralement un problème lorsque les affiches posent des questions sur un tableau, mais fournissent un exemple de liste. Ici, c'est simplement un ennui. Cela dit, np.array_split fonctionne un peu comme votre 2ème solution, en utilisant des tranches. Mais il attend un tuple cumulatif.


@hpaulj Vous avez raison ... désolé pour ça.


5 Réponses :


0
votes

Une manière plus simple est la suivante:

a = [0, 1, 2, 3, 4, 5, 6, 7]
b = (3, 3, 2)

for ind in b:
    print(a[:ind])
    a = a[ind:]

Il parcourt les tailles de tranche dans b tout en raccourcissant le tableau d'origine à chaque fois. Vous pouvez facilement ajouter les tranches résultantes en tant que sous-listes si vous en avez besoin pour autre chose. C'est presque comme l'une de vos solutions, sauf qu'elle n'utilise aucune variable supplémentaire et itère directement à travers des éléments de b .

De plus, je n'appellerais pas les variables a et b - sûrement pas dans ce cas où les variables ont des significations claires que vous pouvez exprimer à travers leurs noms. Des noms plus significatifs réduisent le nombre de bogues et rendent le code plus clair, deviennent une vraie différence avec un code plus grand / plus complexe. J'appellerais a au moins in_list et b slices , mais avec plus de contexte, cela pourrait être mieux.


0 commentaires

2
votes

Si vous ne souhaitez pas modifier votre liste d’entrée, vous pouvez utiliser un itérateur et le module itertools .

>>> from itertools import islice
>>> a = [0, 1, 2, 3, 4, 5, 6, 7]
>>> b = (3, 3, 2)
>>> i = iter(a)
>>> [list(islice(i, x)) for x in b]
[[0, 1, 2], [3, 4, 5], [6, 7]]

Dans la première étape, vous créez un itérateur, qui commence au premier élément de a . Ensuite, vous itérez dans une compréhension de liste sur vos nombres dans b et à chaque étape, vous tirez en conséquence de nombreux éléments de l'itérateur et les stockez dans votre liste de résultats.


0 commentaires

0
votes

La syntaxe la plus "concise" serait:

ex_array = [0, 1, 2, 3, 4, 5, 6, 7] extuple = (3, 3, 2)

result = [ex_array[sum(extuple[:iii]):sum(extuple[:iii])+extuple[iii]] for iii in range(len(extuple))]

le résultat serait une liste des sous-listes attendues


0 commentaires

2
votes

vous pouvez utiliser la méthode de division de numpy

import numpy as np

a = [0, 1, 2, 3, 4, 5, 6, 7]
b = (3, 3, 2)

c = np.split(a, np.cumsum(b)[:-1])

for r in c:
    print(r)

np.split (a, b) divise a par les indices de b le long d'un axe donné (0 par défaut). p >


0 commentaires

0
votes

Réutilisation de la fonction par paire de Comparer deux éléments adjacents dans la même liste , vous pouvez aussi:

from itertools import accumulate
from more_itertools import pairwise

a = [0, 1, 2, 3, 4, 5, 6, 7]
b = (3, 3, 2)

[a[slice(*s)] for s in pairwise(accumulate((0,)+b))]

Cela dit, la réponse np.split est probablement plus rapide (et plus facile à lire ).


0 commentaires