본문 바로가기

파이썬3

numpy를 이용하여 데이터 값의 분포를 binning후 숫자 세기.

728x90
반응형

1. 개요

 데이터의 분포가 어떻게 나타나는지는 여러방법이 있다. 그중에는 값의 최대와 최소를 일정한 구간으로 나눈 후에 값들이 어떻게 각 구간 별로 분포하는지 확인하는 법이 있다. 즉 히스토그램을 만든다고 생각하면 된다.

이를 위해서 numpy에서는 쉬운 기능을 제공한다.

 

2. 방법

사용하는 것은 np.linspace와 np.digitize 그리고 np.bincount 이다.

 

np.linspace (min, max, bins) : 최소와 최대 구간을 정해진 구간 (bins)만큼으로 일정하게 나눠준다.

np.digitize (data, binned_values) : 주어진 data를 np.linspace를 통해 나온 구간의 index로 변환해준다.

np.bincount(digitized) : np.digitize에 나온 index의 숫자가 각각 몇 개인지 세준다. 이렇게 하면 data를 binning하는 과정이 끝난다.

 

3. 주의할점

  • np.digitize를 할 때 문제는 정해진 bin보다 1개가 더 생길 수 있다는 점이다. 이유는 정해진 최소 미만의 값도 몇 개가 있는지 확인하기 때문이다.
  • np.bincount로 나오는 것에서 중간에 빠진 것들은  사라진다. 무슨 뜻이냐면 어떤 구간에서 0인 것들이 있을 수 있는데 이것들은 index상에 그냥 없어서 빠지게 된다. 예를들어 구간은 99, 100이 있어야 하는데 np.digitize로 나오는게 되는 index의 최대값이 98이라면 99와 100은 빠지게 된다.

 

이 부분은 항상 조심해야한다. 자세한 것은 실습코드를 보면 된다.

 

 

# numpy array를 이용하는 법
import numpy as np
#data = abs(np.random.random(100));bins = np.linspace(0, 1, 101)
data = [0,0,1,1,3];bins = np.linspace(0, 100, 101)
digitized = np.digitize(data, bins)
np_bins=np.bincount(digitized) #array로 출력된다.

def mannual_binning(d,b):
    b2=[]
    for idx,value in enumerate(b[:-1]):
        b2.append(sum((d>=value) & (d<b[idx+1])))
    return b2

mannual_bins=mannual_binning(d=data,b=bins)


np_bins[1:]==np.array(mannual_bins)
# False


# function
def bin_count(data,bins):
    import numpy as np
    digitized=np.digitize(data,bins)
    bin_stat=np.bincount(digitized)
    if len(bin_stat)<len(bins):
        short=np.array([0]*(len(bins)-len(bin_stat)))
        bin_stat=np.concatenate([bin_stat,short])
    return bin_stat[1:]
    
bin_count(data,bins)==mannual_bins
# True
728x90
반응형