GVKun编程网logo

在numpy数组中查找最接近的值(numpy找到在数组中的位置)

26

这篇文章主要围绕在numpy数组中查找最接近的值和numpy找到在数组中的位置展开,旨在为您提供一份详细的参考资料。我们将全面介绍在numpy数组中查找最接近的值的优缺点,解答numpy找到在数组中的

这篇文章主要围绕在numpy数组中查找最接近的值numpy找到在数组中的位置展开,旨在为您提供一份详细的参考资料。我们将全面介绍在numpy数组中查找最接近的值的优缺点,解答numpy找到在数组中的位置的相关问题,同时也会为您带来C# – 从十进制数组中查找最接近的索引、NumPy:向量化为另一个数组中的每个元素在数组中找到最接近的值、numpy:如何在numpy数组的每一列中查找第一个非零值?、Python-在numpy数组中查找多个值的行索引的实用方法。

本文目录一览:

在numpy数组中查找最接近的值(numpy找到在数组中的位置)

在numpy数组中查找最接近的值(numpy找到在数组中的位置)

是否有numpy-thonic方法(例如函数)在数组中查找最接近的值?

例:

np.find_nearest( array, value )

答案1

小编典典
import numpy as npdef find_nearest(array, value):    array = np.asarray(array)    idx = (np.abs(array - value)).argmin()    return array[idx]array = np.random.random(10)print(array)# [ 0.21069679  0.61290182  0.63425412  0.84635244  0.91599191  0.00213826#   0.17104965  0.56874386  0.57319379  0.28719469]value = 0.5print(find_nearest(array, value))# 0.568743859261

C# – 从十进制数组中查找最接近的索引

C# – 从十进制数组中查找最接近的索引

decimal[] array = new decimal[5]{80.23,60.20,88.01,77.00,20.45};

decimal TargetNumber = 70.40;

这里,最近的值是77.00,如何找到最接近的十进制数组的索引?

注意:它应该保持与我需要的最接近值的精确索引相同的顺序.在这里,指数比价值重要

解决方法

关于使用LINQ做很多事情的一个好处是,如果找到完全匹配,你可以提前停止检查. minIndex保存索引,如果数组为空,则保持-1.
decimal mindistance = 0; //0 is fine here it is never read,it is just to make the compiler happy.
int minIndex = -1;

for(int i = 0; i < array.Length; i++)
{
    var distance = Math.Abs(TargetNumber - array[i]);
    if(minIndex == -1 || distance < mindistance)
    {
        mindistance = distance;
        minIndex = i;

        //Optional,stop testing if we find a exact match.
        if(mindistance == 0)
            break;
    }
}

为了好玩,我制作了一个完全通用的版本,它要求你传入一个委托来计算距离因子,它还有一个可选参数来定义停止检查更多结果所需的“最小距离”.

using System;
using System.Collections.Generic;

public class Program
{
    public static void Main()
    {
        decimal[] array = new decimal[5]{80.23M,80.40M,80.80M,80.00M,20.45M};
        decimal TargetNumber = 70.40M;

        var result = FindClosestIndex(TargetNumber,array,(target,element) => Math.Abs(target - element)); //Optionally add in a "(distance) => distance == 0" at the end to enable early termination.

        Console.WriteLine(result);
    }

    public static int FindClosestIndex<T,U>(T target,IEnumerable<T> elements,Func<T,T,U> distanceCalculator,Func<U,bool> earlyTermination = null) where U : IComparable<U>
    {
        U mindistance = default(U);
        int minIndex = -1;

        using(var enumerator = elements.GetEnumerator())
        for(int i = 0; enumerator.MoveNext(); i++)
        {

            var distance = distanceCalculator(enumerator.Current,target);
            if(minIndex == -1 || mindistance.Compareto(distance) > 0)
            {
                mindistance = distance;
                minIndex = i;
            }

            if(earlyTermination != null && earlyTermination(mindistance))
                break;
        }

        return minIndex;
    }
}

Runnable example

NumPy:向量化为另一个数组中的每个元素在数组中找到最接近的值

NumPy:向量化为另一个数组中的每个元素在数组中找到最接近的值

输入项

known_array:numpy数组; 仅由标量值组成;shape: (m, 1)

test_array:numpy数组; 仅由标量值组成;shape: (n, 1)

输出量

indices:numpy数组; shape: (n, 1); 对于in
test_array中的每个值,查找in中最接近的值的索引known_array

residual:numpy数组; shape: (n, 1); 对于in
test_array中的每个值,查找与in中最接近的值的差known_array

In [17]: known_array = np.array([random.randint(-30,30) for i in range(5)])In [18]: known_arrayOut[18]: array([-24, -18, -13, -30,  29])In [19]: test_array = np.array([random.randint(-10,10) for i in range(10)])In [20]: test_arrayOut[20]: array([-6,  4, -6,  4,  8, -4,  8, -6,  2,  8])

示例实现(未完全向量化)

def find_nearest(known_array, value):    idx = (np.abs(known_array - value)).argmin()    diff = known_array[idx] - value    return [idx, -diff]In [22]: indices = np.zeros(len(test_array))In [23]: residual = np.zeros(len(test_array))In [24]: for i in range(len(test_array)):   ....:     [indices[i], residual[i]] =  find_nearest(known_array, test_array[i])   ....:In [25]: indicesOut[25]: array([ 2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.,  2.])In [26]: residualOut[26]: array([  7.,  17.,   7.,  17.,  21.,   9.,  21.,   7.,  15.,  21.])

加快此任务的最佳方法是什么?Cython是一个选项,但是,我始终希望能够删除for循环并让代码保留为纯NumPy。


更新

我做了一些小的基准测试来比较非矢量化和矢量化解决方案(可接受的答案)。

In [48]: [indices1, residual1] = find_nearest_vectorized(known_array, test_array)In [53]: [indices2, residual2] = find_nearest_non_vectorized(known_array, test_array)In [54]: indices1==indices2Out[54]: array([ True,  True,  True,  True,  True,  True,  True,  True,  True,  True],   dtype=bool)In [55]: residual1==residual2Out[55]: array([ True,  True,  True,  True,  True,  True,  True,  True,  True,  True], dtype=bool)In [56]: %timeit [indices2, residual2] = find_nearest_non_vectorized(known_array, test_array)10000 loops, best of 3: 173 µs per loopIn [57]: %timeit [indices1, residual1] = find_nearest_vectorized(known_array, test_array)100000 loops, best of 3: 16.8 µs per loop

加速约 10倍

澄清度

known_array 未排序。

我按照下面@cyborg的答案运行了基准测试。

情况1 :如果known_array已排序

known_array = np.arange(0,1000)test_array = np.random.randint(0, 100, 10000)print(''Speedups:'')base_time = time_f(''base'')for func_name in [''diffs'', ''searchsorted1'', ''searchsorted2'']:    print func_name + '' is x%.1f faster than base.'' % (base_time / time_f(func_name))    assert np.allclose(base(known_array, test_array), eval(func_name+''(known_array, test_array)''))

Speedups:diffs is x0.4 faster than base.searchsorted1 is x81.3 faster than base.searchsorted2 is x107.6 faster than base.

首先,对于大型数组,diffs方法实际上要慢一些,它还会占用大量RAM,而当我在实际数据上运行它时,系统就会挂起。

情况2 :何时known_array未排序;代表实际情况

known_array = np.random.randint(0,100,100)test_array = np.random.randint(0, 100, 100)

Speedups:diffs is x8.9 faster than base.AssertionError                            Traceback (most recent call last)<ipython-input-26-3170078c217a> in <module>()      5 for func_name in [''diffs'', ''searchsorted1'', ''searchsorted2'']:      6     print func_name + '' is x%.1f faster than base.'' % (base_time /  time_f(func_name))----> 7     assert np.allclose(base(known_array, test_array),  eval(func_name+''(known_array, test_array)''))AssertionError:searchsorted1 is x14.8 faster than base.

我还必须评论说,该方法还应该具有存储效率。否则我的8 GB RAM不足。在基本情况下,这很容易满足。

答案1

小编典典

例如,您可以计算使用中的所有差异:

differences = (test_array.reshape(1,-1) - known_array.reshape(-1,1))

以及使用argmin和花式索引以及np.diagonal获得所需的索引和差异:

indices = np.abs(differences).argmin(axis=0)residual = np.diagonal(differences[indices,])

因此对于

>>> known_array = np.array([-24, -18, -13, -30,  29])>>> test_array = np.array([-6,  4, -6,  4,  8, -4,  8, -6,  2,  8])

一送一

>>> indicesarray([2, 2, 2, 2, 2, 2, 2, 2, 2, 2])>>> residualarray([ 7, 17,  7, 17, 21,  9, 21,  7, 15, 21])

numpy:如何在numpy数组的每一列中查找第一个非零值?

numpy:如何在numpy数组的每一列中查找第一个非零值?

假设我有以下形式的numpy数组:

arr=numpy.array([[1,1,0],[1,1,0],[0,0,1],[0,0,0]])

我想找到第一个索引(对于每一列)的索引,其中值非零。

因此,在这种情况下,我希望返回以下内容:

[0,0,2]

我该怎么办?

答案1

小编典典

首次出现的指标

使用np.argmax沿轴(零轴这里列)非零的面具拿到第一的指标matches(真实值)

(arr!=0).argmax(axis=0)

扩展到涵盖通用轴说明符,并且在沿着该轴找不到元素的非零的情况下,我们将有一个类似的实现-

def first_nonzero(arr, axis, invalid_val=-1):    mask = arr!=0    return np.where(mask.any(axis=axis), mask.argmax(axis=axis), invalid_val)

请注意,由于argmax()所有False值都会返回0,因此如果invalid_val需要的话0,我们将直接使用生成最终输出mask.argmax(axis=axis)

样品运行-

In [296]: arr    # Different from given sample for varietyOut[296]: array([[1, 0, 0],       [1, 1, 0],       [0, 1, 0],       [0, 0, 0]])In [297]: first_nonzero(arr, axis=0, invalid_val=-1)Out[297]: array([ 0,  1, -1])In [298]: first_nonzero(arr, axis=1, invalid_val=-1)Out[298]: array([ 0,  0,  1, -1])

扩展到涵盖所有比较操作

为了找到第一zeros,简单地使用arr==0作为mask在功能使用。对于等于某个特定值的第一个valarr ==valcomparisons此处对所有可能的情况使用等等。


最近一次出现的指标

要找到符合特定比较标准的最后一个,我们需要沿该轴翻转,并使用相同的用法argmax,然后通过偏离轴长来补偿该翻转,如下所示-

def last_nonzero(arr, axis, invalid_val=-1):    mask = arr!=0    val = arr.shape[axis] - np.flip(mask, axis=axis).argmax(axis=axis) - 1    return np.where(mask.any(axis=axis), val, invalid_val)

样品运行-

In [320]: arrOut[320]: array([[1, 0, 0],       [1, 1, 0],       [0, 1, 0],       [0, 0, 0]])In [321]: last_nonzero(arr, axis=0, invalid_val=-1)Out[321]: array([ 1,  2, -1])In [322]: last_nonzero(arr, axis=1, invalid_val=-1)Out[322]: array([ 0,  1,  1, -1])

同样,comparisons这里所有可能的情况都通过使用相应的比较器进行获取mask,然后在列出的函数中使用来覆盖。

Python-在numpy数组中查找多个值的行索引

Python-在numpy数组中查找多个值的行索引

如何解决Python-在numpy数组中查找多个值的行索引?

方法1

一种方法是NumPy broadcasting像这样

np.where((X==searched_values[:,None]).all(-1))[1]

方法#2

一种内存有效的方法是将每一行转换为等效的线性索引,然后使用np.in1d,例如,

dims = X.max(0)+1
out = np.where(np.in1d(np.ravel_multi_index(X.T,dims),\
                    np.ravel_multi_index(searched_values.T,dims)))[0]

方法3

使用np.searchsorted并具有转换为线性索引等效项的相同原理的另一种内存有效方法将是这样的-

dims = X.max(0)+1
X1D = np.ravel_multi_index(X.T,dims)
searched_valuesID = np.ravel_multi_index(searched_values.T,dims)
sidx = X1D.argsort()
out = sidx[np.searchsorted(X1D,searched_valuesID,sorter=sidx)]

请注意,此np.searchsorted方法假定searched_valuesin 中的每一行都有一个匹配项X。

此函数为我们提供了线性索引当量数。它接受,设置为列的2D数组n-dimensional indices和该n维网格本身的形状,这些索引将映射到该n维网格上并计算等效的线性索引。

让我们使用针对当前问题的输入。以输入为例,X并注意输入的第一行。由于我们正在尝试将的每一行X转换为其等效的线性索引,并且由于np.ravel_multi_index将每一列都假定为一个索引元组,因此我们需要X在转入函数之前进行转置。由于X在这种情况下每行元素的数量为2,因此要映射到的n维网格将为2D。每行中有3个元素X,它本来是3D用于映射的网格,依此类推。

要查看此功能将如何计算线性指标,考虑的第一行X

In [77]: X
Out[77]: 
array([[4, 2],
       [9, 3],
       [8, 5],
       [3, 3],
       [5, 6]])

我们将n维网格的形状设为dims

In [78]: dims
Out[78]: array([10,  7])

让我们创建一个二维网格,以查看该映射如何工作以及如何使用np.ravel_multi_index 计算线性索引

In [79]: out = np.zeros(dims,dtype=int)

In [80]: out
Out[80]: 
array([[0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0]])

让我们从设置第一个索引元组X,即从X网格开始的第一行-

In [81]: out[4,2] = 1

In [82]: out
Out[82]: 
array([[0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0]])

现在,要查看刚设置的元素的线性索引等效项,我们将其展平并用于np.where检测1。

In [83]: np.where(out.ravel())[0]
Out[83]: array([30])

如果考虑行优先排序,也可以计算得出。

让我们使用np.ravel_multi_index并验证这些线性指标-

In [84]: np.ravel_multi_index(X.T,dims)
Out[84]: array([30, 66, 61, 24, 41])

因此,我们将具有对应于from中每个索引元组X(即from中的每一行)的线性索引X。

选择尺寸np.ravel_multi_index以形成唯一的线性索引

现在,将每行X作为n维网格的索引元组并将每个这样的元组转换为标量的想法是要具有与唯一元组相对应的唯一标量,即中的唯一行X。

让我们再来看一看X

In [77]: X
Out[77]: 
array([[4, 2],
       [9, 3],
       [8, 5],
       [3, 3],
       [5, 6]])

现在,如前一节所述,我们将每一行都视为索引元组。在每个这样的索引元组中,第一个元素将代表n-dim网格的第一个轴,第二个元素将是网格的第二个轴,依此类推,直到中的每一行的最后一个元素X。本质上,每一列将代表网格的一个维度或轴。如果我们要将所有元素映射X到同一n-dim网格,则需要考虑这样一个建议的n-dim网格的每个轴的最大拉伸。假设我们在中处理正数X,则这样的延展将是X+ 1 中每一列的最大值。这+ 1是因为Python遵循0-based索引。因此,例如,X[1,0] == 9将映射到第十行拟议的网格。同样,X[4,1] == 6将转到7th该网格的列。

因此,对于我们的示例案例,我们有-

In [7]: dims = X.max(axis=0) + 1 # Or simply X.max(0) + 1

In [8]: dims
Out[8]: array([10,  7])

因此,(10,7)对于样本盒,我们将需要至少一个形状为的网格。沿尺寸的更多长度不会受到损害,并且也会为我们提供独特的线性指标。

结束语:这里要注意的一件重要事情是,如果我们有负数X,则需要在每列中添加适当的偏移量,X以使使用索引的那些元组成为正数np.ravel_multi_index

解决方法

我有一个数组X

X = np.array([[4,2],[9,3],[8,5],[3,[5,6]])

我希望在此数组中找到多个值的行的索引:

searched_values = np.array([[4,6]])

对于此示例,我想要一个类似的结果:

[0,3,4]

我有一个执行此操作的代码,但我认为它过于复杂:

X = np.array([[4,6]])

searched_values = np.array([[4,6]])

result = []

for s in searched_values:
    idx = np.argwhere([np.all((X-s)==0,axis=1)])[0][1]
    result.append(idx)

print(result)

我找到了类似问题的答案,但仅适用于一维数组。

有没有一种方法可以更简单地完成我想要的工作?

关于在numpy数组中查找最接近的值numpy找到在数组中的位置的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于C# – 从十进制数组中查找最接近的索引、NumPy:向量化为另一个数组中的每个元素在数组中找到最接近的值、numpy:如何在numpy数组的每一列中查找第一个非零值?、Python-在numpy数组中查找多个值的行索引的相关知识,请在本站寻找。

本文标签: