2010-10-07 35 views
10

No he podido encontrar esta función en ninguno de los paquetes estándar, así que escribí el siguiente. Sin embargo, antes de lanzarlo hacia Cheeseshop, ¿alguien sabe de una versión ya publicada? Alternativamente, sugiera cualquier mejora. Gracias.Tukey resumen de cinco números en Python

def fivenum(v): 
    """Returns Tukey's five number summary (minimum, lower-hinge, median, upper-hinge, maximum) for the input vector, a list or array of numbers based on 1.5 times the interquartile distance""" 
    import numpy as np 
    from scipy.stats import scoreatpercentile 
    try: 
     np.sum(v) 
    except TypeError: 
     print('Error: you must provide a list or array of only numbers') 
    q1 = scoreatpercentile(v,25) 
    q3 = scoreatpercentile(v,75) 
    iqd = q3-q1 
    md = np.median(v) 
    whisker = 1.5*iqd 
    return np.min(v), md-whisker, md, md+whisker, np.max(v), 
+0

Por si sirve de algo, de matplotlib 'boxplot' http://matplotlib.sourceforge.net/api/pyplot_api.html#matplotlib.pyplot.boxplot efectivamente hace esto, aunque llamándolo simplemente para calcular los parámetros sería torpe, por decir lo menos ... –

+0

El diagrama de cajas de Matlab NO calcula un resumen de 5 números. Q1 y la bisagra inferior son frecuentemente idénticos, ¡pero no siempre! El diagrama de caja calcula Q1 usando un método determinado (también hay muchos que eligen), pero no se garantiza que produzca la bisagra inferior de Tukey. – russellpierce

+0

Cf. http: //stats.stackexchange.com/preguntas/51801/interpretación-raro-box-plot/51806? NoRedirect = 1 # comment101742_51806 – russellpierce

Respuesta

9

Me gustaría deshacerse de estas dos cosas:

import numpy as np 
from scipy.stats import scoreatpercentile 

Debe estar importando a nivel de módulo. Esto significa que los usuarios conocerán las dependencias faltantes tan pronto como importen su módulo, en lugar de cuando llaman a la función.

try: 
    sum(v) 
except TypeError: 
    print('Error: you must provide a list or array of only numbers') 

varios problemas con esta:

  1. No te tipo de comprobación en Python. Documente lo que la función toma.
  2. ¿Cómo sabes que las personas que llaman verán esto? Puede que no se estén ejecutando en una consola, e incluso si lo están, es posible que no quieran que su mensaje de error interfiera con su salida.
  3. No escriba check en Python.

Si desea levantar algún tipo de excepción para datos no válidos (no tipo de control), o bien dejar que una excepción existente propagar o envolverlo en su propio tipo de excepción.

+0

Buenos comentarios tanto. Las importaciones están allí como un marcador de posición para cuando será un módulo. El manejo de excepciones también lo tomaré. Gracias. –

+0

Ya tiene un módulo (en python, todo el código está contenido en un módulo). Solo haga sus importaciones en el nivel superior, fuera de la función. No solo es posiblemente "más correcto", sino que si agrega otra función al archivo, no tendrá que volver a escribir las instrucciones de importación. –

+0

No es exactamente correcto para referirse a lo que está sucediendo como la comprobación de tipos, sólo mala informe de errores. El código deja libre el código del cliente para llamarlo con 'v' igual a cualquier cosa que se pueda pasar a' sum'. Eso es completamente correcto. – aaronasterling

5

En caso de que alguien necesite una versión que funcione con NaN en los datos, esta es mi modificación. No quería cambiar la respuesta del póster original para evitar confusiones.

import numpy as np 
from scipy.stats import scoreatpercentile 
from scipy.stats import nanmedian 

def fivenum(v): 
    """Returns Tukey's five number summary (minimum, lower-hinge, median, upper-hinge, maximum) for the input vector, a list or array of numbers based on 1.5 times the interquartile distance""" 
    try: 
     np.sum(v) 
    except TypeError: 
     print('Error: you must provide a list or array of only numbers') 
    q1 = scoreatpercentile(v[~np.isnan(v)],25) 
    q3 = scoreatpercentile(v[~np.isnan(v)],75) 
    iqd = q3-q1 
    md = nanmedian(v) 
    whisker = 1.5*iqd 
    return np.nanmin(v), md-whisker, md, md+whisker, np.nanmax(v), 
0

Soy nuevo en Python, pero el rendimiento se calcula incorrectamente: debe ser max (min (v), q1-whisker) para el límite inferior y min (max (v), q3 + whisker) para el límite superior. Es cómo se hace en R (la función summary()), y eso es lo que se muestra en los diagramas de caja en matplotlib.pyplot y en R.

26

pandasSeries y DataFrame tienen un método describe, que es similar a R 's summary:

In [3]: import numpy as np 

In [4]: import pandas as pd 

In [5]: s = pd.Series(np.random.rand(100)) 

In [6]: s.describe() 
Out[6]: 
count 100.000000 
mean  0.540376 
std  0.296250 
min  0.002514 
25%  0.268722 
50%  0.593436 
75%  0.831067 
max  0.991971 

NAN se manejan correctamente.

+0

N.B. Esto puede darte un resultado diferente al que intentas. Describir puede estar usando un método de interpolación diferente de lo que se requiere para los cuartiles "inferior" y "superior". ver https://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.percentile.html –

0

Prueba esto:

import numpy as np 
import numpy.random 
from statstools import run 
from scipy.stats import scoreatpercentile 

data=np.random.randn(5) 

return (min(data), md-whisker, md, md+whisker, max(data)) 
0

mínima, pero hace el trabajo. :)

import numpy as np 
[round(np.percentile(results[:,4], i), 1) for i in [1, 2, 5, 10, 25, 50]] 
Cuestiones relacionadas