Python - 在二维网格上合并 x、y、z 值
Python - Binning x,y,z values on a 2D grid
我有一个 z
点列表,与 x,y
对相关联,意思是例如
x y z
3.1 5.2 1.3
4.2 2.3 9.3
5.6 9.8 3.5
等等。 z
值的总数比较高,在 10000 左右。
我想在以下意义上对我的数据进行分类:
1) 我想将 x
和 y
值拆分到单元格中,以便在 x,y
中制作二维网格。如果我有 Nx
轴的 x
单元格和 y
轴的 Ny
单元格,然后我会在网格上有 Nx*Ny
个单元格。例如,x
的第一个 bin 范围从 1. 到 2.,第二个 bin 从 2. 到 3. 等等。
2) 对于二维网格中的每个单元格,我需要计算有多少点落入该单元格,然后将它们的所有 z
值相加。这为我提供了与每个单元格关联的数值。
我考虑过使用 scipy.stats
中的 binned_statistic
,但我不知道如何设置选项来完成我的任务。有什么建议么? binned_statistic
以外的其他工具也被广泛接受。
假设我理解,你可以通过利用 expand_binnumbers 参数获得你需要的 binned_statistic_2d , 因此.
from scipy.stats import binned_statistic_2d
import numpy as np
x = [0.1, 0.1, 0.1, 0.6]
y = [2.1, 2.6, 2.1, 2.1]
z = [2.,3.,5.,7.]
binx = [0.0, 0.5, 1.0]
biny = [2.0, 2.5, 3.0]
ret = binned_statistic_2d(x, y, None, 'count', bins=[binx,biny], \
expand_binnumbers=True)
print (ret.statistic)
print (ret.binnumber)
sums = np.zeros([-1+len(binx), -1+len(biny)])
for i in range(len(x)):
m = ret.binnumber [0][i] - 1
n = ret.binnumber [1][i] - 1
sums[m][n] += sums[m][n] + z[i]
print (sums)
这只是其中一个示例的扩展。这是输出。
[[ 2. 1.]
[ 1. 0.]]
[[1 1 1 2]
[1 2 1 1]]
[[ 9. 3.]
[ 7. 0.]]
建立单元格的边缘,迭代单元格边缘并使用布尔索引提取每个单元格中的 z 值,将总和保存在列表中,转换列表并重塑它。
import itertools
import numpy as np
x = np.array([0.1, 0.1, 0.1, 0.6, 1.2, 2.1])
y = np.array([2.1, 2.6, 2.1, 2.1, 3.4, 4.7])
z = np.array([2., 3., 5., 7., 10, 20])
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
return itertools.izip(a, b)
minx, maxx = int(min(x)), int(max(x)) + 1
miny, maxy = int(min(y)), int(max(y)) + 1
result = []
x_edges = pairwise(xrange(minx, maxx + 1))
for xleft, xright in x_edges:
xmask = np.logical_and(x >= xleft, x < xright)
y_edges = pairwise(xrange(miny, maxy + 1))
for yleft, yright in y_edges:
ymask = np.logical_and(y >= yleft, y < yright)
cell = z[np.logical_and(xmask, ymask)]
result.append(cell.sum())
result = np.array(result).reshape((maxx - minx, maxy - miny))
>>> result
array([[ 17., 0., 0.],
[ 0., 10., 0.],
[ 0., 0., 20.]])
>>>
不幸的是,没有 numpy 向量化魔法
我有一个 z
点列表,与 x,y
对相关联,意思是例如
x y z
3.1 5.2 1.3
4.2 2.3 9.3
5.6 9.8 3.5
等等。 z
值的总数比较高,在 10000 左右。
我想在以下意义上对我的数据进行分类:
1) 我想将 x
和 y
值拆分到单元格中,以便在 x,y
中制作二维网格。如果我有 Nx
轴的 x
单元格和 y
轴的 Ny
单元格,然后我会在网格上有 Nx*Ny
个单元格。例如,x
的第一个 bin 范围从 1. 到 2.,第二个 bin 从 2. 到 3. 等等。
2) 对于二维网格中的每个单元格,我需要计算有多少点落入该单元格,然后将它们的所有 z
值相加。这为我提供了与每个单元格关联的数值。
我考虑过使用 scipy.stats
中的 binned_statistic
,但我不知道如何设置选项来完成我的任务。有什么建议么? binned_statistic
以外的其他工具也被广泛接受。
假设我理解,你可以通过利用 expand_binnumbers 参数获得你需要的 binned_statistic_2d , 因此.
from scipy.stats import binned_statistic_2d
import numpy as np
x = [0.1, 0.1, 0.1, 0.6]
y = [2.1, 2.6, 2.1, 2.1]
z = [2.,3.,5.,7.]
binx = [0.0, 0.5, 1.0]
biny = [2.0, 2.5, 3.0]
ret = binned_statistic_2d(x, y, None, 'count', bins=[binx,biny], \
expand_binnumbers=True)
print (ret.statistic)
print (ret.binnumber)
sums = np.zeros([-1+len(binx), -1+len(biny)])
for i in range(len(x)):
m = ret.binnumber [0][i] - 1
n = ret.binnumber [1][i] - 1
sums[m][n] += sums[m][n] + z[i]
print (sums)
这只是其中一个示例的扩展。这是输出。
[[ 2. 1.]
[ 1. 0.]]
[[1 1 1 2]
[1 2 1 1]]
[[ 9. 3.]
[ 7. 0.]]
建立单元格的边缘,迭代单元格边缘并使用布尔索引提取每个单元格中的 z 值,将总和保存在列表中,转换列表并重塑它。
import itertools
import numpy as np
x = np.array([0.1, 0.1, 0.1, 0.6, 1.2, 2.1])
y = np.array([2.1, 2.6, 2.1, 2.1, 3.4, 4.7])
z = np.array([2., 3., 5., 7., 10, 20])
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = itertools.tee(iterable)
next(b, None)
return itertools.izip(a, b)
minx, maxx = int(min(x)), int(max(x)) + 1
miny, maxy = int(min(y)), int(max(y)) + 1
result = []
x_edges = pairwise(xrange(minx, maxx + 1))
for xleft, xright in x_edges:
xmask = np.logical_and(x >= xleft, x < xright)
y_edges = pairwise(xrange(miny, maxy + 1))
for yleft, yright in y_edges:
ymask = np.logical_and(y >= yleft, y < yright)
cell = z[np.logical_and(xmask, ymask)]
result.append(cell.sum())
result = np.array(result).reshape((maxx - minx, maxy - miny))
>>> result
array([[ 17., 0., 0.],
[ 0., 10., 0.],
[ 0., 0., 20.]])
>>>
不幸的是,没有 numpy 向量化魔法