2013-10-07 5 views
1

numpy.histogram2d 나를 위해 2 배열에있는 데이터를 십자가에 데이터를 보려고하는 중이 야. 전에이 기능을 사용 해본 적이 없으며 수정 방법을 모르는 오류가 발생합니다. 다음과 같은 오류에문제가 numpy.histogram2d와

import numpy as np 
import random 
zones = np.zeros((20,30), int) 
values = np.zeros((20,30), int) 
for i in range(20): 
    for j in range(30): 
     values[i,j] = random.randint(0,10) 
zones[:8,:15] = 100 
zones[8:,:15] = 101 
zones[:8,15:] = 102 
zones[8:,15:] = 103 
np.histogram2d(zones,values) 

이 코드 결과 :

여기
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-18-53447df32000> in <module>() 
----> 1 np.histogram2d(zones,values) 

C:\Python27\ArcGISx6410.2\lib\site-packages\numpy\lib\twodim_base.pyc in histogram2d(x, y, bins, range, normed, weights) 
    613   xedges = yedges = asarray(bins, float) 
    614   bins = [xedges, yedges] 
--> 615  hist, edges = histogramdd([x,y], bins, range, normed, weights) 
    616  return hist, edges[0], edges[1] 
    617 

C:\Python27\ArcGISx6410.2\lib\site-packages\numpy\lib\function_base.pyc in histogramdd(sample, bins, range, normed, weights) 
    279   # Sample is a sequence of 1D arrays. 
    280   sample = atleast_2d(sample).T 
--> 281   N, D = sample.shape 
    282 
    283  nbin = empty(D, int) 

ValueError: too many values to unpack 

내가 달성하기 위해 노력하고 무엇은 :

나는 두 배열을 가지고있다. 하나의 배열은 Landcover 클래스 (예 : 1 = Tree, 2 = Grass, 3 = Building 등)를 나타내는 지리 데이터 집합 (래스터)에서 가져옵니다. 다른 배열은 일종의 정치적 경계 (예 : 소포, 센서스 블록, 도시 등)를 나타내는 지리 데이터 집합 (래스터)에서 가져옵니다. 각 고유 한 정치적 경계 영역 (배열 값은 고유 한 ID를 나타냄)을 행으로 표시하고 각 토지 덮개 클래스의 각 경계 내 총 픽셀 수를 열로 표시하는 표를 얻으려고합니다.

답변

2

저는 zones이 정치적 경계이며 토지 표지는 values이라고 가정합니다. np.bincount을 사용하는 것이 좋을 수 있는데, 이는 각 빈의 간격과 너비가 정확히 1 인 특수 히스토그램과 같습니다.

import numpy as np 

zones = np.zeros((20,30), int) 
zones[:8,:15] = 100 
zones[8:,:15] = 101 
zones[:8,15:] = 102 
zones[8:,15:] = 103 

values = np.random.randint(0,10,(20,30)) # no need for that loop 

tab = np.array([np.bincount(values[zones==zone]) for zone in np.unique(zones)]) 

당신은 빈의 가장자리에주의 경우 당신은,하지만, 히스토그램과 더 간단하게이 작업을 수행 할 수 있습니다 다음과 같이 작동

np.histogram2d(zones.flatten(), values.flatten(), bins=[np.unique(zones).size, values.max()-values.min()+1]) 

방법입니다. 가장 쉬운 예는 지역에 관계없이 모든 값을 살펴 보는 것입니다 : 당신에게 각각의 값 (0 ~ 10)에 대한 카운트 한 행을 제공

np.bincount(values) 

. 다음 단계는 영역을 살펴 보는 것입니다. 한 영역의 경우, 당신은 단지 하나의 행이있을 것이다, 그것은 다음과 같습니다

zone = 101   # the desired zone 
mask = zone==zones # a mask that is True wherever your zones map matches the desired zone 
np.bincount(values[mask]) # count the values where the mask is True 

지금, 우리가지도에서 각 영역에 대해이 작업을 수행 할 수. 그런 다음

tab = np.array([np.bincount(values[zones==zone]) for zone in np.unique(zones)]) 

: 각 항목이 상기와 행의 하나 인 지능형리스트와 그것을 통해

zs = np.unique(zones) 

및 루프와 매핑하여 지역의 고유 한 값의 목록을 얻을 수 있습니다 테이블은 다음과 같습니다

print tab 
# elements with cover = 
# 0 1 2 3 4 5 6 7 8 9  # in zone: 
[[16 11 10 12 13 15 11 7 13 12] # 100 
[13 23 15 16 24 16 24 21 15 13] # 101 
[10 12 23 13 12 11 11 5 11 12] # 102 
[19 25 20 12 16 19 13 18 22 16]] # 103 

을 마지막으로, 당신은 그렇게하기 matplotlib이를 플롯 할 수 있습니다 :

import matplotlib.pyplot as plt 

plt.hist2d(zones.flatten(), values.flatten(), bins=[np.unique(zones).size, values.max()-values.min()+1]) 
+0

감사합니다. 유망 해 보입니다. 얼마나 많은 영역이나 값의 픽셀이 많은지 얼마나 잘 수행 할 수 있는지 알고 있습니까? 예를 들어, 단일 영역에 수천 개의 셀이 포함되어있는 것은 전례가 없습니다. – Brian

+0

충분히 빠르지 만, 이것은 numpy가 만들어지는 것입니다. 그러나 알 수있는 유일한 방법은 그것을 테스트하는 것입니다. 존이 순차적이면,'np.histogram2d'를 사용하는 것이 더 빠르지 만, 그렇지 않다면'np.unique (존)의 존'에 대한리스트 이해를해야 할 것입니다. – askewchan

2

histogram2d는 1D 배열을 입력으로 예상하고 영역과 값은 2D입니다. 당신은 라벨로 선형화 수 :

np.histogram2d(zones.ravel(), values.ravel()) 
+0

좋은 점,'ravel()'은 내 대답과 같이 복사본을 만드는'flatten()'대신보기를 반환합니다. – askewchan

1

을 효율성이 중요하지 않은 경우, 나는이 당신이 키가 어디에 키/발 튜플을 포함

from collections import Counter 

c = Counter(zip(zones.flat[:], landcover_classes.flat[:])) 

C를 수행 할 작업을 위해 작동 생각 튜플 (zone, landcover class).당신이 i와 j가 제로 (즉, 0에서 니켈과 0 뉴저지에)에서 시작하는 순차적 인 정수가있는 경우에만, 물론 작동

for (i, j), count in c.items(): 
    my_table[i, j] = count 

과 같은 경우 배열을 채울 수 있습니다.