Python 从三个1D numpy阵列填充二维numpy阵列

Python 从三个1D numpy阵列填充二维numpy阵列,python,numpy,Python,Numpy,是否有一种有效的方法可以从未排序的坐标点(即并非所有LON和/或LAT都是升序或降序的)创建二维值数组而不使用循环 示例数据 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]) 示例输出 每列

是否有一种有效的方法可以从未排序的坐标点(即并非所有LON和/或LAT都是升序或降序的)创建二维值数组而不使用循环

示例数据

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)

不过,这并不是那么简单,因为我不一定知道每个lon或lat有多少个副本,它们决定了阵列的形状

更新:

我的问题的数据安排不正确。我现在已经安排好了,所以它们都是唯一的对,并且还有一个额外的数据点来演示当存在NAN时应该如何安排数据。

如果要创建2D阵列,那么所有阵列都必须具有相同数量的点。如果这是真的,你可以简单地做

out = np.vstack((lats, lons, vals))

编辑 我想这可能是你想要的,至少符合你的问题:)

然后,如果您的数据表现良好

out = [vals[i] for i, (x, y) in enumerate(zip(lats, lons))]
out = np.asarray(out).reshape((xsize, ysize))
屈服

[[  3.   4.   5.  nan]
 [  6.   7.   7.   4.]
 [  9.   1.   0.  nan]]

您发布的示例没有什么意义,也不允许以任何合理的方式指定缺少的数据。我在这里猜测,但你可能正在处理的唯一合理的事情似乎是这样的:

>>> 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.]])


我认为我的措辞很糟糕,但我希望最终得到一个维度数组(len(lats),len(lon))只包含它们各自坐标的值。但是
lats
lons
不是整数值-所以它们不能整齐地放入大小为
(max(lats),max(lon))的网格中。我错过了什么吗?对不起,这些是列表,所以它是列表的长度(即元素的整数),但我刚刚意识到我真正想要的是len(lats)/重复lat的数量,等等。请参阅我对问题的更新。输出数组的大小由什么决定?
lats
lons
中非重复值的数量?没错。。。我想:)你能用语言解释一下使示例输出所需答案的规范吗?当100不是
VAL
中的值时,指示输出中应放置100的逻辑是什么?为什么?那只是个错误,我道歉。它应该是一个附加值,我没有将其放入值数组中。现在正在更正。这看起来很好,但我一直得到一个
ValueError:新数组的总大小必须保持不变
。我猜我在某个地方弄混了一些东西,因为这和danodonovan的答案都非常直截了当。而且,你的输出是正确的。我遇到的错误是当我在实际的数据集/脚本中使用它时,而不是示例。
ValueError
表示
len(vals)
不等于
len(np.unique(lats))*len(np.unique(lons))
。如果
len(vals)
太长,是否要截断
vals
?如果
len(vals)
太短,是否用
0
s填充数组的其余部分?还有很多其他的可能性…啊。。。我发现我的LAT比LON的独一无二(都是独一无二的)。我想我想用缺少的值(如NaN或-9999)或任何合适的值来填充其余的值。您有没有建议的方法来填充空白?它似乎不直接支持这一点。谢谢Jaime。这也是一个很好的答案,非常有帮助。我为这个可怜的例子道歉。我发现有时很难在不添加不必要的信息来混淆问题的情况下完善我的问题。我想我得到了一些没有意义的地方。lat/lon/value数据应为唯一对,且顺序一致;但是,没有一个列表是严格按升序或降序排列的。我已经正确地对事物进行了重新排序(因此它们是唯一的),并添加了一个值,以演示当存在NAN时输出应该如何。谢谢你的帮助@shootingstars您编辑的示例输入仍然与预期输出不一致。但我现在更确信,我上面提出的是你们想要的。在您的示例输入上尝试它(在
100
添加到
vals
数组之后!),看看您得到了什么,理解为什么它与您期望的不同,我认为您最终会意识到上面的方法是可行的。是的,这非常有效,而且似乎比使用视图更清晰。我的输出数组中的
100
vals
数组中缺少新值是一个纸对键盘错误:)很抱歉我的误解和打字错误,再次感谢您的帮助!这很有启发性。谢谢Jaime,我花了几个小时寻找这样的解决方案!
>>> 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])
>>> 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.]])