Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为另一个数组中的所有浮点查找数组中最近的浮点_Python_Arrays_Performance_Algorithm_Numpy - Fatal编程技术网

Python 为另一个数组中的所有浮点查找数组中最近的浮点

Python 为另一个数组中的所有浮点查找数组中最近的浮点,python,arrays,performance,algorithm,numpy,Python,Arrays,Performance,Algorithm,Numpy,根据在另一个数组中找到的最接近的浮点值“过滤”数组时出现性能问题 这是问题的MWE: import numpy as np def random_data(N): # Generate some random data. return np.random.uniform(0., 10., N).tolist() # Data lists. N1 = 1500 list1 = [random_data(N1), random_data(N1), random_data(N1)]

根据在另一个数组中找到的最接近的浮点值“过滤”数组时出现性能问题

这是问题的
MWE

import numpy as np

def random_data(N):
    # Generate some random data.
    return np.random.uniform(0., 10., N).tolist()

# Data lists.
N1 = 1500
list1 = [random_data(N1), random_data(N1), random_data(N1)]
list2 = random_data(1000)

# Define list1's range.
min_1, max_1 = min(list1[2]), max(list1[2])

# This list will contain the "filtered" list1.
list4 = [[], [], []]

# Go through each element in list2.
for elem2 in list2:

    # If it is located within the list1 range.
    if min_1 <= elem2 <= max_1:

        # Find the closest float in sub-list list1[2] to this float
        # in list2.
        indx, elem1 = min(enumerate(list1[2]), key=lambda x:abs(x[1]-elem2))

        # Store the values in list1 that are associated with the closest float
        # found above.
        list4[0].append(list1[0][indx])
        list4[1].append(list1[1][indx])
        list4[2].append(elem1)
现在
list1[2]
的范围不等于
list2
的范围,因此给出的答案无法拒绝那些
i
最大值(list1[2])或
list2[i]
的点

可以修改这个答案来考虑这种可能性吗?我很抱歉这样更改了原始代码,我真的错过了。

如果您有SciPy,a可以完成这项工作:

import numpy
import scipy.spatial

array1 = numpy.array(list1)
array2 = numpy.array(list2)

# A tree optimized for nearest-neighbor lookup
tree = scipy.spatial.cKDTree(array1[2, ..., numpy.newaxis])

# The distances from the elements of array2 to their nearest neighbors in
# array1, and the indices of those neighbors.
distances, indices = tree.query(array2[..., numpy.newaxis])

array4 = array1[:, indices]
k-d树是为多维数据而设计的,因此这可能不是最快的解决方案,但与现有的解决方案相比,它应该非常快。k-d树期望以点的2D数组的形式输入,其中,
data[i]
是一个1D数组,表示
i
th点,因此使用带有
newaxis
的切片表达式将数据放入该格式。如果您需要更快的速度,您可以使用
numpy.sort
numpy.searchsorted
进行操作

如果需要拒绝
list2
中超出
list1[2]
给定值范围的数据,可通过预处理步骤完成:

lowbound = array1[2].min()
highbound = array1[2].max()

querypoints = array2[(array2 >= lowbound) & (array2 <= highbound)]
distances, indices = tree.query(querypoints[..., numpy.newaxis])
lowbound=array1[2].min()
上限=阵列1[2]。最大值()

querypoints=array2[(array2>=lowbound)&(array2Kd-tree在这里真是太过分了,你需要做的就是对数组进行排序,并使用二进制搜索在排序后的数组中找到最接近的值。我不久前写过一篇文章,讲述了如何使用
searchsorted
找到数组中目标的密室值。你可以在这里使用相同的想法:

import numpy as np

def find_closest(A, target):
    #A must be sorted
    idx = A.searchsorted(target)
    idx = np.clip(idx, 1, len(A)-1)
    left = A[idx-1]
    right = A[idx]
    idx -= target - left < right - target
    return idx

def random_data(shape):
    # Generate some random data.
    return np.random.uniform(0., 10., shape)

def main(data, target):
    order = data[2, :].argsort()
    key = data[2, order]
    target = target[(target >= key[0]) & (target <= key[-1])]
    closest = find_closest(key, target)
    return data[:, order[closest]]

N1 = 1500
array1 = random_data((3, N1))
array2 = random_data(1000)
array2[[10, 20]] = [-1., 100]

array4 = main(array1, array2)
将numpy导入为np
def find_最接近(A,目标):
#A必须分类
idx=A.searchsorted(目标)
idx=np.clip(idx,1,len(A)-1)
左=A[idx-1]
右=A[idx]
idx-=目标-左<右-目标
返回idx
def随机_数据(形状):
#生成一些随机数据。
返回np.随机均匀(0,10.,形状)
def主(数据、目标):
订单=数据[2,:]。argsort()
键=数据[2,顺序]

target=target[(target>=key[0])&(target这可能属于codereview…但为什么不对列表1[2]进行2c排序,然后将min1、max1分别排序为
[0]
[-1]
…这将使您可以使用二进制搜索更快地找到最近的值…Ithink@JoranBeasley与
O(N)相比,排序为
O(NlogN)
min
max
所花费的时间。因此,
min
max
在这里会更快(至少在理论上)。二进制搜索在这里不起作用,因为OP正在寻找具有最小绝对差异的项的索引。好吧,公平点…他似乎仍然能够在排序列表中更快地找到abs差异…并可能节省足够的时间使排序值得…也许…二进制搜索可以找到最小绝对差异,没有问题。这将返回一个错误:
ValueError:需要多个值才能解包
tree=scipy.spatial.KDTree(array1[2])
行中的
。您可以在此处测试:)好的,已经修复并测试。理论上,它应该可以工作。但是可能需要更多的解释。@Gabriel:还不够?我想KD树实现的开销抵消了更好的渐进运行时带来的许多好处。我将尝试使用
numpy.digitalize
编写一些东西,看看是否效果更好。scipy.spatial.cKDTree wi我很可能会给你增加10倍。注意这里额外的“c”。k-d树确实有些过头了。我之所以选择它,是因为它提供了一个方便的界面,而且比我选择
searchsorted
searchsorted
或类似的东西的机会要小得多,因为如果k-d树太慢的话,备份计划是这样做的。惊人的答案,甚至比用户2357112给出的答案还要快!我不明白最后一行
array2[[10,20]]=[-1,100]
,你这样做是为了什么?它取代了
array[10]
array[20]
使用-1和100。它们在那里,因此我可以检查结果并确保这些值被拒绝。如果我使用了您第二次更新中的代码,我就不需要这一行了。太好了,我现在看到了替换的必要性。我选择这个答案是因为它比user2357112的答案提高了~3倍的速度。非常感谢你们伙计们!
import numpy as np

def find_closest(A, target):
    #A must be sorted
    idx = A.searchsorted(target)
    idx = np.clip(idx, 1, len(A)-1)
    left = A[idx-1]
    right = A[idx]
    idx -= target - left < right - target
    return idx

def random_data(shape):
    # Generate some random data.
    return np.random.uniform(0., 10., shape)

def main(data, target):
    order = data[2, :].argsort()
    key = data[2, order]
    target = target[(target >= key[0]) & (target <= key[-1])]
    closest = find_closest(key, target)
    return data[:, order[closest]]

N1 = 1500
array1 = random_data((3, N1))
array2 = random_data(1000)
array2[[10, 20]] = [-1., 100]

array4 = main(array1, array2)