3 votes

Convertir un tableau numpy de listes en un tableau numpy

J'ai des données qui sont stockées dans un tableau numpy avec dtype=object J'aimerais extraire une colonne de listes et la convertir en un tableau numpy. Cela semble être un problème simple, mais la seule façon que j'ai trouvée pour le résoudre est de refondre l'ensemble en une liste de listes, puis de la refondre en un tableau numpy. Existe-t-il une approche plus pythonique ?

import numpy as np

arr = np.array([[1, ['a', 'b', 'c']], [2, ['a', 'b', 'c']]], dtype=object)
arr = arr[:, 1]

print(arr)
# [['a', 'b', 'c'] ['a', 'b', 'c']]

type(arr)
# numpy.ndarray
type(arr[0])
# list

arr.shape
# (2,)

La refonte du tableau sous forme de dtype=str soulève un ValueError puisqu'il essaie de convertir chaque liste en chaîne de caractères.

arr.astype(str)
# ValueError: setting an array element with a sequence

Il est possible de reconstruire le tableau entier comme une liste de listes et de le convertir en tableau numpy, mais cela semble être un moyen détourné.

arr_2 = np.array(list(arr))

type(arr_2)
# numpy.ndarray
type(arr_2[0])
# numpy.ndarray

arr_2.shape
# (2, 3)

Existe-t-il une meilleure façon de procéder ?

4voto

Divakar Points 20144

Une solution consisterait à utiliser des opérations d'empilement avec quelque chose comme np.vstack -

np.vstack(arr[:, 1])

Exemple d'exécution -

In [234]: arr
Out[234]: 
array([[1, ['a', 'b', 'c']],
       [2, ['a', 'b', 'c']]], dtype=object)

In [235]: arr[:,1]
Out[235]: array([['a', 'b', 'c'], ['a', 'b', 'c']], dtype=object)

In [236]: np.vstack(arr[:, 1])
Out[236]: 
array([['a', 'b', 'c'],
       ['a', 'b', 'c']], 
      dtype='|S1')

Je crois np.vstack utiliserait en interne np.concatenate . Ainsi, pour l'utiliser directement, il faudrait -

np.concatenate(arr[:, 1]).reshape(len(arr),-1)

3voto

hpaulj Points 6132

Bien qu'il soit plus rapide de passer par des listes que de passer par des vstack :

In [1617]: timeit np.array(arr[:,1].tolist())
...
100000 loops, best of 3: 11.5 µs per loop
In [1618]: timeit np.vstack(arr[:,1])
...
10000 loops, best of 3: 54.1 µs per loop

vstack est en train de faire :

np.concatenate([np.atleast_2d(a) for a in arr[:,1]],axis=0)

Quelques alternatives :

In [1627]: timeit np.array([a for a in arr[:,1]])
100000 loops, best of 3: 18.6 µs per loop
In [1629]: timeit np.stack(arr[:,1],axis=0)
10000 loops, best of 3: 60.2 µs per loop

Gardez à l'esprit que le tableau d'objets ne contient que des pointeurs vers les listes qui se trouvent ailleurs dans la mémoire. Bien que la nature 2d de arr facilite la sélection de la deuxième colonne, arr[:,1] est en fait une liste de listes. La plupart des opérations effectuées sur cette liste la traitent comme telle. Des choses comme reshape ne le franchissez pas object limite.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X