简体   繁体   English

将值插入到已排序的数组中

[英]Inserting values into a sorted array

What would be the quickest way to insert values into the correct position in a sorted numpy array?在已排序的 numpy 数组中将值插入正确位置的最快方法是什么?

For example, I would like to insert every value of b into a :例如,我想将b每个值插入到a

a = [1,1,2,4,7,7,11,13,13,13,15,20,25,26,27,30,45,70]

b = [5,7,9,45]

I've tried looping through a for each value of b and inserting it that way.我试图通过循环a对的每个值b和插入这种方式。 I've also tried the bisect_left method:我也试过bisect_left方法:

for i in b:
a.insert(bisect_left(a,i),i)

Both methods are too slow as I have hundreds of thousands of data elements to go through.这两种方法都太慢了,因为我要处理数十万个数据元素。

Any ideas?有什么想法吗?

You could use searchsorted and insert :您可以使用searchsortedinsert

a = numpy.array([1,1,2,4,7,7,11,13,13,13,15,20,25,26,27,30,45,70])
b = numpy.array([5,7,9,45])
ii = numpy.searchsorted(a, b)
a = numpy.insert(a, ii, b)

Just use builtin sort method.只需使用内置sort方法。 It implements timsort .它实现了timsort If the list is almost sorted, it will be very fast.如果列表几乎排序,它将非常快。

a.extend(b)
a.sort()

let's note n = len(a) and m = len(b) ,让我们注意n = len(a) and m = len(b)

  1. you can use a binary search to find each element's position and insert it, that would done in m*n*log(n) time您可以使用二分搜索来查找每个元素的位置并插入它,这将在m*n*log(n)时间内完成
  2. you can merge both arrays, that would have an n+m complexity您可以合并两个数组,这将具有 n+m 复杂度
  3. you can use a specialized structure, a balanced binary tree, you can find a lot of implementation of these in python, the time complexity will be mlog(n)你可以使用一个专门的结构,一个平衡的二叉树,你可以在python中找到很多这些实现,时间复杂度将是mlog(n)

Now given possible values of n and m, you can determine which solution is best, but don't expect to do better than that现在给定 n 和 m 的可能值,您可以确定哪个解决方案是最好的,但不要期望做得更好

For a more pythonic approach, You can use bisect.insort(your_list, your_value) to insert a value into the correct position of a sorted list.对于更bisect.insort(your_list, your_value)方法,您可以使用bisect.insort(your_list, your_value)将值插入到排序列表的正确位置。 Like this:像这样:

import bisect

a = [1,1,2,4,7,7,11,13,13,13,15,20,25,26,27,30,45,70]
b = [5,7,9,45]

for value in b:
    bisect.insort(a, value)

# Now a == [1, 1, 2, 4, 5, 7, 7, 7, 9, 11, 13, 13, 13, 15, 20, 25, 26, 27, 30, 45, 45, 70]

You solution slow becaue you have a lot of inserts.你的解决方案很慢,因为你有很多插入。 Each insrt is O(N) complexity.每个插入都是 O(N) 复杂度。

My solution: a = [1,1,2,4,7,7,11,13,13,13,15,20,25,26,27,30,45,70] b = [5,7,9,45]我的解决方案:a = [1,1,2,4,7,7,11,13,13,13,15,20,25,26,27,30,45,70] b = [5,7,9 ,45]

insert b.Length items into end of a.将 b.Length 项插入到 a 的末尾。 a = [1,1,2,4,7,7,11,13,13,13,15,20,25,26,27,30,45,70,x,x,x,x] b = [5,7,9,45] a = [1,1,2,4,7,7,11,13,13,13,15,20,25,26,27,30,45,70,x,x,x,x] b = [ 5,7,9,45]

Take 3 pointers:拿3个指点:

  1. Pointer into a to last actual element(in example pointer to 70 )指针到一个到最后一个实际元件(例如,在指针70)
  2. Pointer into b to last element(in example pointer to 45 )指向b指向最后一个元素的指针(例如指向45 的指针)
  3. POinter to last of a指向最后a指针

Here my solution in C#:这是我在 C# 中的解决方案:

    int p1 = a.Length - 1;
    int p2 = b.Length - 1;
    int p3 = a.Length + b.Length - 1;

    //Insert b.Length items to end of a.

    while (p3 >= 0 && p2 >= 0)
    {
        if (p1 < 0 || b[p2] >= a[p1])
        {
            a[p3--] = b[p2--];
        }
        else
        {
            a[p3--] = a[p1--];
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM