Deseo obtener una lista de los datos contenidos en un contenedor de histogramas. Estoy usando numpy y Matplotlib. Sé cómo recorrer los datos y verificar los bordes de los contenedores. Sin embargo, quiero hacer esto para un histograma 2D y el código para hacer esto es bastante feo. ¿Numpy tiene construcciones para hacer esto más fácil?Cómo obtener datos en un contenedor de histogramas
Para el caso 1D, puedo usar searchsorted(). Pero la lógica no es mucho mejor, y realmente no quiero hacer una búsqueda binaria en cada punto de datos cuando no es necesario.
La mayor parte de la desagradable lógica se debe a las regiones de límite de la bandeja. Todas las regiones tienen límites como este: [borde izquierdo, borde derecho]. Excepto el último contenedor, que tiene una región como esta: [borde izquierdo, borde derecho].
Aquí hay un código de ejemplo para el caso 1D:
import numpy as np
data = [0, 0.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 3]
hist, edges = np.histogram(data, bins=3)
print 'data =', data
print 'histogram =', hist
print 'edges =', edges
getbin = 2 #0, 1, or 2
print '---'
print 'alg 1:'
#for i in range(len(data)):
for d in data:
if d >= edges[getbin]:
if (getbin == len(edges)-2) or d < edges[getbin+1]:
print 'found:', d
#end if
#end if
#end for
print '---'
print 'alg 2:'
for d in data:
val = np.searchsorted(edges, d, side='right')-1
if val == getbin or val == len(edges)-1:
print 'found:', d
#end if
#end for
Aquí hay un código de ejemplo para el caso 2D:
import numpy as np
xdata = [0, 1.5, 1.5, 2.5, 2.5, 2.5, \
0.5, 0.5, 0.5, 0.5, 1.5, 1.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, \
0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 2.5, 3]
ydata = [0, 5,5, 5, 5, 5, \
15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, \
25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 30]
xbins = 3
ybins = 3
hist2d, xedges, yedges = np.histogram2d(xdata, ydata, bins=(xbins, ybins))
print 'data2d =', zip(xdata, ydata)
print 'hist2d ='
print hist2d
print 'xedges =', xedges
print 'yedges =', yedges
getbin2d = 5 #0 through 8
print 'find data in bin #', getbin2d
xedge_i = getbin2d % xbins
yedge_i = int(getbin2d/xbins) #IMPORTANT: this is xbins
for x, y in zip(xdata, ydata):
# x and y left edges
if x >= xedges[xedge_i] and y >= yedges[yedge_i]:
#x right edge
if xedge_i == xbins-1 or x < xedges[xedge_i + 1]:
#y right edge
if yedge_i == ybins-1 or y < yedges[yedge_i + 1]:
print 'found:', x, y
#end if
#end if
#end if
#end for
¿Existe un/forma más eficiente limpiador para hacer esto? Parece que Numpy tendría algo para esto.
Sólo por curiosidad; ¿Por qué usas comentarios como #end si está en tu código? "Cada píxel cuenta" Al hacer eso, estás ignorando el propósito de la sangría. –
2 razones. Primero soy desarrollador de C++ y desarrollador de python en segundo lugar. La falta de llaves de Python me irrita sin fin. Cuando tengo bloques de código complicados con muchas indentaciones variables, no quiero contar espacios en blanco. Y hago la mayor parte de mi desarrollo en Emacs. Al poner comentarios de cierre en bloques de código, me permite presionar TAB en cada línea y Emacs no intentará indebidamente algo. – Ben