簡體   English   中英

Python Numpy:基於坐標創建二維值數組

[英]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數組。 在此先感謝您的幫助!

假設文件中的xy值直接對應於索引(如示例中所示),則可以執行以下操作:

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輸入不一致

如果您定期采樣x和y點,則可以通過減去網格的“角”(即x0y0 ),除以像元間距並將其轉換為整數來將它們轉換為網格索引。 然后,您可以使用上面的方法,也可以在其他任何答案中使用。

作為一般示例:

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.histogramweights參數僅添加值。 在這種情況下,這可能不是您想要的。 盡管如此,我們可以通過除以計數來獲得每個單元格中落點的平均值。

舉例來說,假設我們有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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM