我正在尝试查看numpy.histogram2d
是否会为我列出2个数组中的数据。我之前从未使用过此功能,而且我收到错误,我不知道如何修复。
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
这是我想要完成的事情:
我有2个数组。一个数组来自代表Landcover类的地理数据集(栅格)(例如1 =树,2 =草,3 =建筑等)。另一个数组来自代表某种政治边界的地理数据集(栅格)(例如地块,人口普查区,城镇等)。我试图得到一个表格,列出每个独特的政治边界区域(数组值代表一个唯一的id)作为行,每个边界内每个边界内的像素总数列为列。
答案 0 :(得分:2)
我假设values
是土地覆盖,zones
是政治边界。您可能希望使用np.bincount
,这就像一个特殊的直方图,其中每个bin的间距和宽度恰好为一个。
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)])
如果您对bin边缘小心,可以使用直方图更简单地执行此操作:
np.histogram2d(zones.flatten(), values.flatten(), bins=[np.unique(zones).size, values.max()-values.min()+1])
其工作方式如下。最简单的示例是查看所有值,而不考虑区域:
np.bincount(values)
为您提供一行,其中包含每个值的计数(0到10)。下一步是查看区域。 对于一个区域,您只有一行,它将是:
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
现在,我们只想对地图中的每个区域执行此操作。您可以使用
获取区域地图中唯一值的列表zs = np.unique(zones)
并使用列表推导循环遍历它,其中每个项目都是上面的行之一:
tab = np.array([np.bincount(values[zones==zone]) for zone in 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])
答案 1 :(得分:2)
histogram2d期望1D数组作为输入,您的区域和值是2D。你可以用ravel来线性化它们:
np.histogram2d(zones.ravel(), values.ravel())
答案 2 :(得分:1)
如果效率不是问题,我认为这适用于您想要做的事情
from collections import Counter
c = Counter(zip(zones.flat[:], landcover_classes.flat[:]))
c将包含key / val元组,其中键是(zone,landcover类)的元组。如果您愿意,可以使用
填充数组for (i, j), count in c.items():
my_table[i, j] = count
当然,只有当i和j是从零开始的连续整数(即从0到Ni和0到Nj)时才有效。