[英]Python numpy: create 2d array of values based on coordinates
我有一个包含3列的文件,其中前两列是坐标(x,y),第三列是对应于该位置的值(z)。 这是一个简短的示例:
x y z
0 1 14
0 2 17
1 0 15
1 1 16
2 1 18
2 2 13
我想根据文件中的x,y坐标从第三行创建2D值数组。 我将每一列读为一个单独的数组,并使用numpy.meshgrid创建了x值和y值的网格,如下所示:
x = [[0 1 2] and y = [[0 0 0]
[0 1 2] [1 1 1]
[0 1 2]] [2 2 2]]
但是我是Python的新手,不知道如何生成第三个z值网格,如下所示:
z = [[Nan 15 Nan]
[14 16 18]
[17 Nan 13]]
用0
替换Nan
也可以; 我的主要问题是首先创建2D数组。 在此先感谢您的帮助!
假设文件中的x
和y
值直接对应于索引(如示例中所示),则可以执行以下操作:
import numpy as np
x = [0, 0, 1, 1, 2, 2]
y = [1, 2, 0, 1, 1, 2]
z = [14, 17, 15, 16, 18, 13]
z_array = np.nan * np.empty((3,3))
z_array[y, x] = z
print z_array
产生:
[[ nan 15. nan]
[ 14. 16. 18.]
[ 17. nan 13.]]
对于大型数组,这将比坐标上的显式循环快得多。
如果您定期采样x和y点,则可以通过减去网格的“角”(即x0
和y0
),除以像元间距并将其转换为整数来将它们转换为网格索引。 然后,您可以使用上面的方法,也可以在其他任何答案中使用。
作为一般示例:
i = ((y - y0) / dy).astype(int)
j = ((x - x0) / dx).astype(int)
grid[i,j] = z
但是,如果您的数据没有规则排列,则可以使用一些技巧。
假设我们有以下数据:
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1977)
x, y, z = np.random.random((3, 10))
fig, ax = plt.subplots()
scat = ax.scatter(x, y, c=z, s=200)
fig.colorbar(scat)
ax.margins(0.05)
我们要放入常规的10x10网格中:
我们实际上可以为此使用/滥用np.histogram2d
。 代替计数,我们将其添加到单元格中的每个点的值。 通过指定weights=z, normed=False
最容易做到这一点。
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1977)
x, y, z = np.random.random((3, 10))
# Bin the data onto a 10x10 grid
# Have to reverse x & y due to row-first indexing
zi, yi, xi = np.histogram2d(y, x, bins=(10,10), weights=z, normed=False)
zi = np.ma.masked_equal(zi, 0)
fig, ax = plt.subplots()
ax.pcolormesh(xi, yi, zi, edgecolors='black')
scat = ax.scatter(x, y, c=z, s=200)
fig.colorbar(scat)
ax.margins(0.05)
plt.show()
但是,如果我们有大量的点,则某些箱将具有多个点。 np.histogram
的weights
参数仅添加值。 在这种情况下,这可能不是您想要的。 尽管如此,我们可以通过除以计数来获得每个单元格中落点的平均值。
举例来说,假设我们有50分:
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(1977)
x, y, z = np.random.random((3, 50))
# Bin the data onto a 10x10 grid
# Have to reverse x & y due to row-first indexing
zi, yi, xi = np.histogram2d(y, x, bins=(10,10), weights=z, normed=False)
counts, _, _ = np.histogram2d(y, x, bins=(10,10))
zi = zi / counts
zi = np.ma.masked_invalid(zi)
fig, ax = plt.subplots()
ax.pcolormesh(xi, yi, zi, edgecolors='black')
scat = ax.scatter(x, y, c=z, s=200)
fig.colorbar(scat)
ax.margins(0.05)
plt.show()
点数非常多时,这种精确的方法会变慢(并且可以轻松加速),但对于少于1e6点的东西就足够了。
您可以尝试类似:
import numpy as np
x = [0, 0, 1, 1, 2, 2]
y = [1, 2, 0, 1, 1, 2]
z = [14, 17, 15, 16, 18, 13]
arr = np.zeros((3,3))
yx = zip(y,x)
for i, coord in enumerate(yx):
arr[coord] = z[i]
print arr
>>> [[ 0. 15. 0.]
[ 14. 16. 18.]
[ 17. 0. 13.]]
Kezzos击败了我,但我采取了类似的方法,
x = np.array([0,0,1,1,2,2])
y = np.array([1,2,0,1,1,2])
z = np.array([14,17,15,16,18,13])
Z = np.zeros((3,3))
for i,j in enumerate(zip(x,y)):
Z[j] = z[i]
Z[np.where(Z==0)] = np.nan
如果您安装了scipy
,则可以利用其sparse
矩阵模块。 使用genfromtxt
从文本文件中获取值,然后将这些“列”直接插入sparse
矩阵创建器中。
In [545]: txt=b"""x y z
0 1 14
0 2 17
1 0 15
1 1 16
2 1 18
2 2 13
"""
In [546]: xyz=np.genfromtxt(txt.splitlines(),names=True,dtype=int)
In [547]: sparse.coo_matrix((xyz['z'],(xyz['y'],xyz['x']))).A
Out[547]:
array([[ 0, 15, 0],
[14, 16, 18],
[17, 0, 13]])
但是乔的z_array=np.zeros((3,3),int); z_array[xyz['y'],xyz['x']]=xyz['z']
z_array=np.zeros((3,3),int); z_array[xyz['y'],xyz['x']]=xyz['z']
的速度要快得多。
别人的好答案。 认为这对于可能需要此功能的其他人可能是有用的代码段。
def make_grid(x, y, z):
'''
Takes x, y, z values as lists and returns a 2D numpy array
'''
dx = abs(np.sort(list(set(x)))[1] - np.sort(list(set(x)))[0])
dy = abs(np.sort(list(set(y)))[1] - np.sort(list(set(y)))[0])
i = ((x - min(x)) / dx).astype(int) # Longitudes
j = ((y - max(y)) / dy).astype(int) # Latitudes
grid = np.nan * np.empty((len(set(j)),len(set(i))))
grid[-j, i] = z # if using latitude and longitude (for WGS/West)
return grid
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.