En Python 2 je pourrais faire ce qui suit:
import numpy as np
f = lambda x: x**2
seq = map(f, xrange(5))
seq = np.array(seq)
print seq
# prints: [ 0 1 4 9 16]
En Python 3 cela ne fonctionne plus:
import numpy as np
f = lambda x: x**2
seq = map(f, range(5))
seq = np.array(seq)
print(seq)
# prints: <map object at 0x10341e310>
Comment obtenir l'ancien comportement (conversion des résultats map
en tableau numpy
)?
Edit: Comme @jonrsharpe l'a souligné dans sa réponse, cela pourrait être corrigé si je convertissais d'abord seq
en liste:
seq = np.array(list(seq))
mais je préfère éviter l'appel supplémentaire à list
.
Une autre alternative, autre que les solutions valides @jonrsharpe déjà signalées, consiste à utiliser np.fromiter
:
>>> import numpy as np
>>> f = lambda x: x**2
>>> seq = map(f, range(5))
>>> np.fromiter(seq, dtype=np.int)
array([ 0, 1, 4, 9, 16])
Bien que vous l'appeliez seq
, l'objet map
dans Python 3 n'est pas pas une séquence (c'est un itérateur, voir ce qui est nouveau dans Python ). numpy.array
A besoin d'une séquence pour que le len
puisse être déterminé et la quantité appropriée de mémoire réservée; il ne consommera pas d'itérateur. Par exemple, l'objet range
, qui le fait prend en charge la plupart des opérations de séquence, peut être transmis directement;
seq = np.array(range(5))
print(seq)
# prints: [0 1 2 3 4]
Pour restaurer le comportement précédent, comme vous le savez, vous pouvez explicitement reconvertir l'objet map
en une séquence (par exemple, liste ou Tuple):
seq = np.array(list(seq)) # should probably change the name!
Cependant, comme la documentation le dit:
une solution rapide consiste à envelopper
map()
danslist()
, par exemplelist(map(...))
, mais une meilleure solution consiste souvent à utiliser une compréhension de liste (en particulier lorsque le code d'origine utiliselambda
)
Une autre option serait donc:
seq = [f(x) for x in range(5)]
ou juste:
seq = [x**2 for x in range(5)]
Vous pouvez également utiliser numpy
dès le début:
import numpy as np
arr = np.arange(5)
arr **= 2
print(arr)
# prints [ 0 1 4 9 16] in 2.x and 3.x