Python Numpy:对应于唯一坐标位置的值的平均值
所以,我浏览stackoverflow已经有一段时间了,但我似乎找不到解决问题的方法 想想这个Python Numpy:对应于唯一坐标位置的值的平均值,python,arrays,numpy,Python,Arrays,Numpy,所以,我浏览stackoverflow已经有一段时间了,但我似乎找不到解决问题的方法 想想这个 import numpy as np coo = np.array([[1, 2], [2, 3], [3, 4], [3, 4], [1, 2], [5, 6], [1, 2]]) values = np.array([1, 2, 4, 2, 1, 6, 1]) coo数组包含(x,y)坐标位置 x=(1,2,3,3,1,5,1) y=(2,3,4,4,2,6,2) 这些值数组是这个网格点的某种数
import numpy as np
coo = np.array([[1, 2], [2, 3], [3, 4], [3, 4], [1, 2], [5, 6], [1, 2]])
values = np.array([1, 2, 4, 2, 1, 6, 1])
coo数组包含(x,y)坐标位置
x=(1,2,3,3,1,5,1)
y=(2,3,4,4,2,6,2)
这些值数组是这个网格点的某种数据
现在我想得到每个唯一网格点的所有值的平均值。
例如,坐标(1,2)出现在位置(0,4,6)处,因此对于这一点,我需要值[[0,4,6]]
我如何才能为所有唯一的网格点获取此信息?您可以使用排序
coo
来连续获取重复的网格点。然后沿行运行,以获得排序版本中唯一XY的起始掩码。使用该掩码,您可以创建一个ID数组,该数组对于重复项具有相同的ID。然后,ID数组可以与一起使用,以获得具有相同ID的所有值的总和,以及它们的计数和平均值,作为最终输出。下面是一个按照这些思路进行的实现-
# Use lexsort to bring duplicate coo XY's in succession
sortidx = np.lexsort(coo.T)
sorted_coo = coo[sortidx]
# Get mask of start of each unique coo XY
unqID_mask = np.append(True,np.any(np.diff(sorted_coo,axis=0),axis=1))
# Tag/ID each coo XY based on their uniqueness among others
ID = unqID_mask.cumsum()-1
# Get unique coo XY's
unq_coo = sorted_coo[unqID_mask]
# Finally use bincount to get the summation of all coo within same IDs
# and their counts and thus the average values
average_values = np.bincount(ID,values[sortidx])/np.bincount(ID)
样本运行-
In [65]: coo
Out[65]:
array([[1, 2],
[2, 3],
[3, 4],
[3, 4],
[1, 2],
[5, 6],
[1, 2]])
In [66]: values
Out[66]: array([1, 2, 4, 2, 1, 6, 1])
In [67]: unq_coo
Out[67]:
array([[1, 2],
[2, 3],
[3, 4],
[5, 6]])
In [68]: average_values
Out[68]: array([ 1., 2., 3., 6.])
您可以在以下位置使用
:
>>> values[np.where((coo == [1, 2]).all(1))].mean()
1.0
很可能会更快地平展指数,即:
flat_index = coo[:, 0] * np.max(coo[:, 1]) + coo[:, 1]
然后在其上使用np.unique
:
unq, unq_idx, unq_inv, unq_cnt = np.unique(flat_index,
return_index=True,
return_inverse=True,
return_counts=True)
unique_coo = coo[unq_idx]
unique_mean = np.bincount(unq_inv, values) / unq_cnt
与使用lexsort
的类似方法相比
但在引擎盖下,方法实际上是相同的。这是一个使用该软件包的简单单内衬(免责声明:我是其作者):
在性能上应与当前公认的答案相当,因为它在引擎盖下做类似的事情;但是所有这些都在一个经过良好测试的软件包中,有一个很好的界面。什么是coo
的数据类型?值是否始终为非负整数?坐标有一个最大值吗?在我的例子中,数据类型是“float”,坐标可以取任意值,也可以取负值@HansSnah我希望你不要在实际应用中尝试对float进行相等检查。:)非常聪明!谢谢我已经在我的代码中实现了它!您可以从diff
结果的索引位置获得计数,这基本上就是np.unique
在请求return\u counts=True
时所做的,它通常比调用bincount
@Jaime-Ah-yeah也可以用于计数更快。不知道与这两种方法相关的性能数据,很高兴知道,谢谢!我想如果我循环所有唯一的值,这会起作用,但我也希望避免这种情况,但我发现,当应用于我的数据时,与lexsort方法相比,中的平面索引不是唯一的,并且某些组合的结果有些不同。这可能是因为我搞砸了:您需要将行索引乘以最大的列索引,而不是最大的行索引。我已经编辑了上面的内容,现在应该可以正常工作了。OP澄清了coo
值可以是浮点数。如果coo=np.array([[0,2],[0.5,1]])
,那么flat_index
将等于array([2,2])
,从而组合两个不同的坐标。谢谢!我很感谢您的评论,但我没有测试/实现您的例程,因为我不想将我所有项目中的依赖项数量保持在尽可能低的水平。它可以在所有平台上安装pip和conda;但这是你的决定。请随意复制粘贴我的回购协议中的相关部分。
import numpy_indexed as npi
unique, mean = npi.group_by(coo).mean(values)