2010-03-29 7 views
1

Quel est le problème avec cet extrait de code?Utilisation de numpy.apply

import numpy as np 
from scipy import stats 

d = np.arange(10.0) 
cutoffs = [stats.scoreatpercentile(d, pct) for pct in range(0, 100, 20)] 
f = lambda x: np.sum(x > cutoffs) 
fv = np.vectorize(f) 

# why don't these two lines output the same values? 
[f(x) for x in d] # => [0, 1, 2, 2, 3, 3, 4, 4, 5, 5] 
fv(d)    # => array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) 

Des idées?

Répondre

1

cutoffs est une liste. Les numéros que vous extrayez de d sont tous transformés en float et appliqués en utilisant numpy.vectorize. (Il est plutôt étrange - il semble d'abord qu'il essaie des flottants numyques qui fonctionnent comme vous voulez puis il essaie des flotteurs Python normaux.) Par un comportement plutôt étrange et stupide en Python, les flotteurs sont toujours moins que des listes,

>>> # Here is a vectorized array operation, like you get from numpy. It won't 
>>> # happen if you just use a float and a list. 
>>> 2.0 > [0.0, 1.8, 3.6, 5.4, 7.2] 
[True, True, False, False, False] # not real 

vous obtenez

>>> # This is an actual copy-paste from a Python interpreter 
>>> 2.0 > [0.0, 1.8, 3.6, 5.4, 7.2] 
False 

Pour résoudre le problème, vous pouvez faire cutoffs un tableau numpy au lieu d'un list. (Vous pourriez probablement aussi déplacer la comparaison en opérations numpy entièrement au lieu de truquer avec numpy.vectorize, mais je ne sais pas désinvolte.)

+0

"les flotteurs sont toujours moins que des listes" n'est pas évidemment "stupide": comment comparez-vous les choses cela ne peut pas être comparé? (comme les pommes et les idées) – EOL

+2

Vous ne le faites pas, c'est pourquoi cela devrait déclencher une exception. (Dans 3.x, comparer une liste et un flottant augmentera 'TypeError', en réalisant que Python ne devrait pas faire des choses qui n'ont aucun sens.) –