Pregunta

Lo que es una buena manera de bin valores numéricos dentro de un cierto rango?Por ejemplo, supongamos que tengo una lista de valores y quiero bin en N contenedores según su rango.Ahora, hago algo como esto:

from scipy import *
num_bins = 3 # number of bins to use
values = # some array of integers...
min_val = min(values) - 1
max_val = max(values) + 1
my_bins = linspace(min_val, max_val, num_bins)
# assign point to my bins
for v in values:
  best_bin = min_index(abs(my_bins - v))

donde min_index devuelve el índice del valor mínimo.La idea es que usted puede encontrar el bin el punto cae en por ver lo que bin tiene la mínima diferencia con.

Pero creo que esto se raros casos de borde.Lo que estoy buscando es una buena representación de los contenedores, idealmente a los que están medio cerrados de medio abierto (de modo que no hay forma de asignar un punto a dos papeleras), es decir,

bin1 = [x1, x2)
bin2 = [x2, x3)
bin3 = [x3, x4)
etc...

lo que es una buena manera de hacer esto en Python, utilizando numpy/scipy?Sólo me interesan aquí con binning valores enteros.

muchas gracias por su ayuda.

¿Fue útil?

Solución

numpy.histogram() hace exactamente lo que usted desea.

La función de la firma es:

numpy.histogram(a, bins=10, range=None, normed=False, weights=None, new=None)

Estamos interesados principalmente en la a y bins. a es la entrada de datos que necesita ser desechado. bins puede ser un número de contenedores (su num_bins), o puede ser una secuencia de escalares, que denotan bin bordes (medio abierto).

import numpy
values = numpy.arange(10, dtype=int)
bins = numpy.arange(-1, 11)
freq, bins = numpy.histogram(values, bins)
# freq is now [0 1 1 1 1 1 1 1 1 1 1]
# bins is unchanged

A la cita documentación:

Todos, pero la última (de la derecha-la mayoría) de reciclaje es semi-abierta.En otras palabras, si bins es:

[1, 2, 3, 4]

a continuación, el primer bin es [1, 2) (1 incluyendo, pero excepto 2) y el segundo [2, 3).El último bin, sin embargo, es [3, 4], que incluye 4.

Editar:Quieres saber el índice en las bandejas de cada elemento.Para esto, puede utilizar numpy.digitize().Si las bandejas van a ser integral, puede usar numpy.bincount() así.

>>> values = numpy.random.randint(0, 20, 10)
>>> values
array([17, 14,  9,  7,  6,  9, 19,  4,  2, 19])
>>> bins = numpy.linspace(-1, 21, 23)
>>> bins
array([ -1.,   0.,   1.,   2.,   3.,   4.,   5.,   6.,   7.,   8.,   9.,
        10.,  11.,  12.,  13.,  14.,  15.,  16.,  17.,  18.,  19.,  20.,
        21.])
>>> pos = numpy.digitize(values, bins)
>>> pos
array([19, 16, 11,  9,  8, 11, 21,  6,  4, 21])

Puesto que el intervalo es abierto en el límite superior, los índices son correctas:

>>> (bins[pos-1] == values).all()
True
>>> import sys
>>> for n in range(len(values)):
...     sys.stdout.write("%g <= %g < %g\n"
...             %(bins[pos[n]-1], values[n], bins[pos[n]]))
17 <= 17 < 18
14 <= 14 < 15
9 <= 9 < 10
7 <= 7 < 8
6 <= 6 < 7
9 <= 9 < 10
19 <= 19 < 20
4 <= 4 < 5
2 <= 2 < 3
19 <= 19 < 20

Otros consejos

Esto es bastante sencillo en numpy usando transmitiendo - (. Sin contar primeros dos líneas para crear contenedores y puntos de datos, lo que por supuesto ordinariamente ser suministrados) mi ejemplo siguiente es cuatro líneas de código

import numpy as NP
# just creating 5 bins at random, each bin expressed as (x, y, z) although, this code
# is not limited by bin number or bin dimension
bins = NP.random.random_integers(10, 99, 15).reshape(5, 3) 
# creating 30 random data points
data = NP.random.random_integers(10, 99, 90).reshape(30, 3)
# for each data point i want the nearest bin, but before i can generate a distance
# matrix, i need to 'conform' the array dimensions
# 'broadcasting' is an excellent and concise way to do this
bins = bins[:, NP.newaxis, :]
data2 = data[NP.newaxis, :, :]
# now i can calculate the distance matrix
dist_matrix = NP.sqrt(NP.sum((data - bins)**2, axis=-1)) 
bin_assignments = NP.argmin(dist_matrix, axis=0)

'bin_assignments' es una matriz de 1d de los índices de compuestos de valores enteros de 0 a 4, correspondientes a los cinco bins -. Las asignaciones de bin para cada uno de los 30 puntos originales en la matriz '' de datos por encima

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top