如何通过索引列表过滤numpy数组?

时间:2013-11-06 19:50:14

标签: python numpy scipy nearest-neighbor lidar

我对python相对较新,一直在努力学习如何使用numpy和scipy。我有一个由LAS数据[x,y,z,强度,分类]组成的numpy数组。我创建了一个cKDTree点,并使用query_ball_point找到了最近的邻居。我想找到query_ball_point返回的邻居的z值的标准偏差,它返回该点及其邻居的索引列表。

有没有办法过滤filtered__rows来创建一个只有其索引位于query_ball_point返回的列表中的点的数组?见下面的代码。我可以将值附加到列表并从中计算std dev,但我认为使用numpy在单个轴上计算std dev会更容易。提前谢谢。

# Import modules
from liblas import file
import numpy as np
import scipy.spatial

if __name__=="__main__":
    '''Read LAS file and create an array to hold X, Y, Z values'''
    # Get file
    las_file = r"E:\Testing\kd-tree_testing\LE_K20_clipped.las"
    # Read file
    f = file.File(las_file, mode='r')
    # Get number of points from header
    num_points = int(f.__len__())
    # Create empty numpy array
    PointsXYZIC = np.empty(shape=(num_points, 5))
    # Load all LAS points into numpy array
    counter = 0
    for p in f:
        newrow = [p.x, p.y, p.z, p.intensity, p.classification]
        PointsXYZIC[counter] = newrow
        counter += 1

    '''Filter array to include classes 1 and 2'''
    # the values to filter against
    unclassified = 1
    ground = 2
    # Create an array of booleans
    filter_array = np.any([PointsXYZIC[:, 4] == 1, PointsXYZIC[:, 4] == 2], axis=0)
    # Use the booleans to index the original array
    filtered_rows = PointsXYZIC[filter_array]

    '''Create a KD tree structure and segment the point cloud'''
    tree = scipy.spatial.cKDTree(filtered_rows, leafsize=10)

    '''For each point in the point cloud use the KD tree to identify nearest neighbors,
       with a K radius'''
    k = 5 #meters
    for pntIndex in range(len(filtered_rows)):
        neighbor_list = tree.query_ball_point(filtered_rows[pntIndex], k)
        zList = []
        for neighbor in neighbor_list:
            neighbor_z = filtered_rows[neighbor, 2]
            zList.append(neighbor_z)

4 个答案:

答案 0 :(得分:25)

嗯,很难说是什么问题(那就是文字的墙)

filter_indices = [1,3,5]
print numpy.array([11,13,155,22,0xff,32,56,88])[filter_indices] 

可能就是你在问什么

答案 1 :(得分:1)

  

您知道多维数组如何转换吗?

通过为每个索引提供一个1d数组,从而为一个2d数组,可以将其扩展为多维数组 filter_indices=np.array([[1,0],[0,1]]) array=np.array([[0,1],[1,2]]) print(array[filter_indices[:,0],filter_indices[:,1])

将给您: [1,1]

Scipy解释了如果您致电会发生什么: print(array[filter_indices])

https://docs.scipy.org/doc/numpy-1.13.0/user/basics.indexing.html

答案 2 :(得分:1)

numpy.take可能非常有用,并且可以很好地用于多维数组。

import numpy as np

filter_indices = [1, 2]
axis = 0
array = np.array([[1, 2, 3, 4, 5], 
                  [10, 20, 30, 40, 50], 
                  [100, 200, 300, 400, 500]])

print(np.take(array, filter_indices, axis))
# [[ 10  20  30  40  50]
#  [100 200 300 400 500]]

axis = 1
print(np.take(array, filter_indices, axis))
# [[  2   3]
#  [ 20  30]
# [200 300]]

答案 3 :(得分:1)

使用文档:https://docs.scipy.org/doc/numpy-1.13.0/user/basics.indexing.html 以下实现应适用于某些numpy ndarray的任意数量的尺寸/形状。

首先,我们需要一个多维索引集和一些示例数据:

import numpy as np
y = np.arange(35).reshape(5,7)
print(y) 
indexlist = [[0,1], [0,2], [3,3]]
print ('indexlist:', indexlist)

要真正提取出直观的结果,诀窍是使用移调:

indexlisttranspose = np.array(indexlist).T.tolist()
print ('indexlist.T:', indexlisttranspose)
print ('y[indexlist.T]:', y[ tuple(indexlisttranspose) ])

产生以下终端输出:

y: [[ 0  1  2  3  4  5  6]
 [ 7  8  9 10 11 12 13]
 [14 15 16 17 18 19 20]
 [21 22 23 24 25 26 27]
 [28 29 30 31 32 33 34]]
indexlist: [[0, 1], [0, 2], [3, 3]]
indexlist.T: [[0, 0, 3], [1, 2, 3]]
y[indexlist.T]: [ 1  2 24]

元组...修复了将来可能引起的警告,如下所示:

print ('y[indexlist.T]:', y[ indexlisttranspose ])
FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`.
In the future this will be interpreted as an array index,
`arr[np.array(seq)]`, which will result either in an error or a
different result.
    print ('y[indexlist.T]:', y[ indexlisttranspose ])
y[indexlist.T]: [ 1  2 24]