从三个1D numpy数组填充2D numpy数组
有没有一种有效的方法,可以在不使用循环的情况下,从无序的坐标点中创建一个二维数组?也就是说,这些坐标的经度和纬度并不是按顺序排列的。
示例数据
lats = np.array([45.5,45.5,45.5,65.3,65.3,65.3,43.2,43.2,43.2,65.3])
lons = np.array([102.5,5.5,116.2,102.5,5.5,116.2,102.5,5.5,116.2,100])
vals = np.array([3,4,5,6,7,7,9,1,0,4])
示例输出
每一列代表一个独特的经度(比如102.5、5.5、116.2和100),而每一行代表一个独特的纬度(比如45.5、65.3和43.2)。
([ 3, 4, 5, NaN],
[ 6, 7, 7, 4],
[ 9, 1, 0, NaN])
不过,这并不是那么简单,因为我并不一定知道每个经度或纬度有多少个重复值,而这些重复值决定了数组的形状。
更新:
我之前的数据排列不正确,现在我已经重新排列好了,确保它们都是独特的配对,并且还增加了一个数据点,以展示在有NaN(缺失值)时,数据应该如何排列。
3 个回答
1
import numpy as np
lats = np.array([45.5,45.5,45.5,65.3,65.3,65.3,43.2,43.2,43.2,65.3])
lons = np.array([102.5,5.5,116.2,102.5,5.5,116.2,102.5,5.5,116.2,100])
vals = np.array([3,4,5,6,7,7,9,1,0,4])
def unique_order(seq):
# http://www.peterbe.com/plog/uniqifiers-benchmark (Dave Kirby)
# Order preserving
seen = set()
return [x for x in seq if x not in seen and not seen.add(x)]
unique_lats, idx_lats = np.unique(lats, return_inverse=True)
unique_lons, idx_lons = np.unique(lons, return_inverse=True)
perm_lats = np.argsort(unique_order(lats))
perm_lons = np.argsort(unique_order(lons))
result = np.empty((len(unique_lats), len(unique_lons)))
result.fill(np.nan)
result[perm_lats[idx_lats], perm_lons[idx_lons]] = vals
print(result)
[[ 3. 4. 5. nan]
[ 6. 7. 7. 4.]
[ 9. 1. 0. nan]]
产生
1
如果你在创建一个二维数组,那么所有的数组都必须有相同数量的元素。如果这个条件成立,你可以简单地这样做:
out = np.vstack((lats, lons, vals))
编辑
我觉得这可能正是你想要的,至少它和你的问题是相关的 :)
xsize = len(np.unique(lats))
ysize = len(np.unique(lons))
然后,如果你的数据表现得很好
out = [vals[i] for i, (x, y) in enumerate(zip(lats, lons))]
out = np.asarray(out).reshape((xsize, ysize))
5
你发的例子看起来没什么意义,也没有合理的方法来处理缺失的数据。我在这里猜测,但你可能在处理的事情大概是这样的:
>>> lats = np.array([43.2, 43.2, 43.2, 45.5, 45.5, 45.5, 65.3, 65.3, 65.3])
>>> lons = np.array([5.5, 102.5, 116.2, 5.5, 102.5, 116.2, 5.5, 102.5, 116.2])
>>> vals = np.array([3, 4, 5, 6, 7, 7, 9, 1, 0])
在这里,vals[j]
的值是根据纬度lats[j]
和经度lons[j]
得来的,不过数据可能会被搞乱,比如:
>>> indices = np.arange(9)
>>> np.random.shuffle(indices)
>>> lats = lats[indices]
>>> lons = lons[indices]
>>> vals = vals[indices]
>>> lats
array([ 45.5, 43.2, 65.3, 45.5, 43.2, 65.3, 45.5, 65.3, 43.2])
>>> lons
array([ 5.5, 116.2, 102.5, 116.2, 5.5, 116.2, 102.5, 5.5, 102.5])
>>> vals
array([6, 5, 1, 7, 3, 0, 7, 9, 4])
你可以按照以下方式把这些数据整理成一个数组:
>>> lat_vals, lat_idx = np.unique(lats, return_inverse=True)
>>> lon_vals, lon_idx = np.unique(lons, return_inverse=True)
>>> vals_array = np.empty(lat_vals.shape + lon_vals.shape)
>>> vals_array.fill(np.nan) # or whatever yor desired missing data flag is
>>> vals_array[lat_idx, lon_idx] = vals
>>> vals_array
array([[ 3., 4., 5.],
[ 6., 7., 7.],
[ 9., 1., 0.]])