2010-12-30 8 views
15

Estoy leyendo en un archivo usando numpy.genfromtxt que trae columnas de ambas cadenas y valores numéricos. Una cosa que tengo que hacer es detectar la longitud de la entrada. Todo esto está bien, siempre que haya más de un valor leído en cada conjunto.¿Cómo se detecta la longitud de una matriz numpy con un solo elemento?

Pero ... si solo hay un elemento en la matriz resultante, la lógica falla. Puedo recrear un ejemplo aquí:

import numpy as np 
a = np.array(2.3) 

len (a) devuelve un error que dice: Sin embargo

TypeError: len() of unsized object 

, si A tiene 2 o más elementos, len() se comporta como cabría esperar.

import numpy as np 
a = np.array([2.3,3.6]) 

len (a) devuelve 2

Mi preocupación aquí es, si uso un poco de manejo de excepciones extraño, no puedo distinguir entre un ser vacío y una longitud que tiene = 1.

EDITAR: @noskio sugirió establecer a = np.Array ([2.3]). El problema es que la génesis real de a es mediante el uso de numpy.genfromtxt. El código es el siguiente:

import numpy as np 
indata = np.genfromtxt(some_filename, names=True,dtype=None) 
a = indata['one_col_headername'] 

Como resultado, si INDATA es sólo una fila en el archivo, a es una matriz 0-d.

+1

'array ([2])' es una matriz con un elemento y 1 dimensión . 'array (2)' es una matriz con cero rango o cero dimensiones. – endolith

Respuesta

32

Si necesita una sola línea (suponiendo que la respuesta que está esperando es 1):

In [1]: import numpy as np 

In [2]: a = np.array(2.3) 

In [3]: len(np.atleast_1d(a)) 
Out[3]: 1 

This page explica por qué se decidió aplicar matrices 0-dimensionales en numpy.

+1

Gracias @pberkes! Eso ayuda a toneladas y resuelve el problema – mishaF

+0

El enlace está roto :( – wim

+2

@wim parece que se ha eliminado el enlace, y no puedo encontrar un reemplazo para él. – pberkes

0
a = np.array([2.3]) 
print len(a) 
+0

esto funciona para una constante como se muestra, pero no para una entrada de matriz – ecoe

6
import numpy as np 

tests=[np.array(2.3),np.array([]),np.array([2.3]),np.array([2.3,3.6])] 

print('{a:30}{s:<10}{l:<10}{sl:<10}'.format(a='repr',s='shape',sl='len(shape)',l='length')) 
for a in tests: 
    s=a.shape 
    l=len(a) if a.shape else 0 
    sl=len(s) 
    print('{a!r:30}{s:<10}{l:<10}{sl:<10}'.format(a=a,l=l,s=s,sl=sl)) 

rendimientos

repr       shape  length len(shape) 
array(2.2999999999999998) ()  0   0   
array([], dtype=float64)  (0,)  0   1   
array([ 2.3])     (1,)  1   1   
array([ 2.3, 3.6])   (2,)  2   1   

Se puede distinguir entre una matriz "vacío" (por ejemplo np.array([])) y un escalar numpy (por ejemplo np.array(2.3)) mirando a la longitud de la forma.

+0

Gracias @unubtu. Eso es genial, pero ¿cómo puedo distinguir entre a con una longitud de 1 y una a vacía? – mishaF

+0

¡Entendido! Eso ayuda a toneladas. – mishaF

3

Parece que la propiedad size de ndarrays funcionará en este caso si sabe que la matriz es unidimensional. En mi opinión, a.size es mucho más legible que len(np.atleast_1d(a)). Sin embargo, en cuenta que la propiedad size devolverá el total de número de elementos en el array si tiene más de una dimensión:

In [1]: import numpy as np 

In [2]: np.array(2.3).size 
Out[2]: 1 

In [3]: np.array([1, 2]).size 
Out[3]: 2 

In [4]: np.array([[1,2], [3,4]]).size 
Out[4]: 4 
Cuestiones relacionadas