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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19821425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 14:43:01  来源:igfitidea点击:

How to filter numpy array by list of indices?

pythonnumpyscipynearest-neighborlidar

提问by Barbarossa

I am relatively new to python and have been trying to learn how to use numpy and scipy. I have a numpy array comprised of LAS data [x, y, z, intensity, classification]. I have created a cKDTree of points and have found nearest neighbors using query_ball_point. I would like to find standard deviation of the z values for the neighbors returned by query_ball_point, which returns a list of indices for the point and its neighbors.

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

Is there a way to filter filtered__rows to create an array of only points whose index is in the list returned by query_ball_point? See code below. I can append the values to a list and calculate std dev from that, but I think it would be easier to use numpy to calculate std dev on a single axis. Thanks in advance.

有没有办法过滤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)

采纳答案by Joran Beasley

ummmm Its hard to tell whats being asked (thats quite the wall of text)

嗯,很难说出被问到的问题(那是一堆文字)

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

may be what you are asking

可能是你要问的

回答by Leaderchicken

Do you know how that translates for multi-dimensional arrays?

你知道多维数组是如何转换的吗?

It can be expanded to multi dimensional arrays by giving a 1d array for every index so for a 2d array filter_indices=np.array([[1,0],[0,1]]) array=np.array([[0,1],[1,2]]) print(array[filter_indices[:,0],filter_indices[:,1])

通过为每个索引提供一维数组,它可以扩展为多维数组,因此对于二维数组 filter_indices=np.array([[1,0],[0,1]]) array=np.array([[0,1],[1,2]]) print(array[filter_indices[:,0],filter_indices[:,1])

will give you : [1,1]

会给你:[1,1]

Scipy has an explanation on what will happen if you call: print(array[filter_indices])

Scipy 有一个解释,如果你打电话会发生什么: print(array[filter_indices])

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

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

回答by gnuchoi

numpy.takecan be useful and works well for multimensional arrays.

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