我使用scipy.spatial.cKDTree.query_ball_point从网格布局中的每个点获取特定半径内的数据点数。
它可以工作,但返回一个列表数组,我只需要每个列表的长度。当然我可以遍历数组,但必须有一种聪明的方法来获取列表数组中每个列表的长度,或者可能是另一种方法来查找每个网格点在特定半径范围内的数据点数
如何最有效地实现这一目标?
答案 0 :(得分:2)
对数组中的每个元素调用len()
即
lengths=[len(x) for x in myarray]
答案 1 :(得分:2)
此函数的文档说它返回
如果x是点数组,则返回包含邻居列表的
shape tuple
对象数组
,其中
x:array_like,
shape tuple
+(self.m,)
关于shape tuple
的讨论有点不清楚,但我认为它指的是x.shape[:-1]
,除了输入数组的最后一个维度。因此,对于二维空间中的n
点,x
将为(n,2)
,结果将为shape(n,)。
对于简单的1d列表数组,只需简单列表理解就是最好的方法:
In [36]: x=np.array([[1,2,3],[],[3,4]])
In [37]: x
Out[37]: array([[1, 2, 3], [], [3, 4]], dtype=object)
In [39]: [len(i) for i in x]
Out[39]: [3, 0, 2]
len(x)
和x.shape
适用于数组本身,而不适用于任何元素。
x
包含指向列表的指针;因此,对这些列表的任何操作都需要Python访问这些列表。没有很多矢量化数组操作向下传播到对象数组的元素。在这样的数组的所有元素之后可以是任何东西,包括None
。
如果您输入的数组是更高维度,例如(10,20,2)
,一个10x20的积分,它可能最容易在第一次扁平化。
In [50]: X
Out[50]:
array([[[1, 2, 3], [1]],
[[1, 2, 3], [3, 4]]], dtype=object)
In [51]: np.array([len(i) for i in X.flat]).reshape(2,2)
Out[51]:
array([[3, 1],
[3, 2]])
总之 - 列表理解是要走的路,即使它是一个数组。
===============
还有另一种迭代处理多维度的数组的方法。在某些测试中,它可以比列表迭代节省20%,使用np.frompyfunc
。
np.frompyfunc(len,1,1)(x).astype(int)
它返回一个正确形状的数组,虽然它也是dtype对象,因此是astype
标记。 np.vectorize
使用此功能,但不提及提高速度。
答案 2 :(得分:1)
您还可以使用更“数学”的方式:
lengths = map(len, myarray)
它将返回您可以迭代的map
对象。
答案 3 :(得分:0)
听起来你正在寻找这个:scipy.spatial.cKDTree.count_neighbors