문제

히스토그램 빈에 포함 된 데이터 목록을 얻고 싶습니다. Numpy와 Matplotlib를 사용하고 있습니다. 데이터를 가로 지르고 빈 가장자리를 확인하는 방법을 알고 있습니다. 그러나 2D 히스토그램을 위해이 작업을하고 싶습니다.이를 수행하는 코드는 다소 추악합니다. Numpy는 이것을 더 쉽게 만들 수있는 구조물이 있습니까?

1D 케이스의 경우 SearchSorted ()를 사용할 수 있습니다. 그러나 논리는 그다지 더 나은 것이 아니며, 필요하지 않을 때 각 데이터 포인트에서 이진 검색을하고 싶지 않습니다.

불쾌한 논리의 대부분은 빈 경계 영역 때문입니다. 모든 지역에는 다음과 같은 경계가 있습니다 : [왼쪽 가장자리, 오른쪽 가장자리). 이와 같은 영역이있는 마지막 빈을 제외하고 : [왼쪽 가장자리, 오른쪽 가장자리].

다음은 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

다음은 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

이 작업을 수행하는 더 깨끗하고 효율적인 방법이 있습니까? Numpy가 이것을 위해 무언가를 가질 것 같습니다.

도움이 되었습니까?

해결책

digitize, Core Numpy에서, 당신에게 당신에게 줄 것입니다 인덱스 히스토그램의 각 값이 속한 빈의 :

import numpy as NP
A = NP.random.randint(0, 10, 100)

bins = NP.array([0., 20., 40., 60., 80., 100.])

# d is an index array holding the bin id for each point in A
d = NP.digitize(A, bins)     

다른 팁

다음과 같은 것은 어떻습니까 :

In [1]: data = numpy.array([0, 0.5, 1.5, 1.5, 1.5, 2.5, 2.5, 2.5, 3])
In [2]: hist, edges = numpy.histogram(data, bins=3)
In [3]: for l, r in zip(edges[:-1], edges[1:]):
    print(data[(data > l) & (data < r)])
   ....:     
   ....:     
[ 0.5]
[ 1.5  1.5  1.5]
[ 2.5  2.5  2.5]
In [4]: 

에지 케이스를 처리하기 위해 약간의 코드가 있습니다.

pyplot.hist Matplotlib에서 히스토그램을 만듭니다 (그러나 화면에도 원하지 않을 수도 있음). 쓰레기통의 경우 다른 답변에 설명 된대로 Numpy.histogram을 사용할 수 있습니다.

여기 pyploy.hist 및 numpy.histogram을 비교하는 예입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top