numpy:如何将两个排序数组合并为一个更大的排序数组?

时间:2019-12-10 08:40:26

标签: python numpy sorting

我说有两个排序的np.arrays

1, 2, 3, 5

2, 4, 6, 7

我想要

1 2 2 3 4 5 6 7

不想让python循环。

为此有一些numpy函数吗?


奖金:对某些轴上的矩阵执行此操作(其他轴具有相同的形状)

5 个答案:

答案 0 :(得分:2)

导入sortednp,就可以了:

import numpy as np
import sortednp as s

a = np.array([1,2,3,5])
b = np.array([2,4,6,7])

m = s.merge(a, b)
print(m)

答案 1 :(得分:2)

滥用输入数组的排序性质,我们可以使用np.searchsorted,就像这样-

def merge_sorted_arrays(a, b):
    m,n = len(a), len(b)
    # Get searchsorted indices
    idx = np.searchsorted(a,b)

    # Offset each searchsorted indices with ranged array to get new positions
    # of b in output array
    b_pos = np.arange(n) + idx

    l = m+n
    mask = np.ones(l,dtype=bool)
    out = np.empty(l,dtype=np.result_type(a,b))
    mask[b_pos] = False
    out[b_pos] = b
    out[mask] = a
    return out

样品运行(使用重复的通用案例)-

In [52]: a
Out[52]: array([1, 2, 3, 3, 5, 9, 9, 9])

In [53]: b
Out[53]: array([ 2,  4,  6,  6,  6,  7, 10])

In [54]: merge_sorted_arrays(a, b)
Out[54]: array([ 1,  2,  2,  3,  3,  4,  5,  6,  6,  6,  7,  9,  9,  9, 10])

随机排序1000000大小的数组上的Timimgs-

使用流行的concatenate + sort方法进行基准测试。

# Setup
In [141]: np.random.seed(0)
     ...: a = np.sort(np.random.randint(0,1000000,(1000000)))
     ...: b = np.sort(np.random.randint(0,1000000,(1000000)))

# @chmod777's soln
In [142]: %%timeit
     ...: c = np.concatenate((a,b), axis=0)
     ...: c.sort()
141 ms ± 2.13 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [143]: %timeit merge_sorted_arrays(a, b)
55.1 ms ± 5.1 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

答案 2 :(得分:0)

不需要安装诸如sortednp之类的其他库的最快选择应该是先使用numpy.concatenate()然后对其进行排序

import numpy as np

a = np.array([1, 2, 3, 5])
b = np.array([2, 4, 6, 7])

c = np.concatenate((a,b), axis=0)
c.sort()

这将导致合并和排序的数组

c = array([1, 2, 2, 3, 4, 5, 6, 7])

答案 3 :(得分:0)

1。

使用列表-

from heapq import merge

arr1 = [1,2,3,5]
arr2 = [2,4,6,7]

print list(merge(arr1, arr2))

2使用Numpy-

import numpy
from numpy import concatenate, sort
arr1 =numpy.array([1,2,3,5])
arr2 =numpy.array([2,4,6,7]) 

print sort(concatenate((arr1,arr2)))

有关使用Link

的更多信息

答案 4 :(得分:0)

numpy开发人员最近实现了tim sort。 tim排序检查预排序子序列时,将对O(n)中两个排序数组的串联进行排序。

由于某些原因,当前无法直接选择tim排序,但是至少在某些情况下kind="stable"导致使用了tim排序。整数类型使用基数排序,该基数也为O(n)。 有关更多详细信息,请参见官方文档https://docs.scipy.org/doc/numpy/reference/generated/numpy.sort.html

大小为10 ^ 6时,与默认排序方法(我相信qsort)相比,它的速度提高了10倍。

tim排序/基数排序也仅比sortednp.merge慢一点。

# default sort
def so():
    c = np.concatenate((a,b))
    c.sort()
    return c

# tim sort / radix sort
def ts():
    c = np.concatenate((a,b))
    c.sort(kind="stable")
    return c

from sortednp import merge

# extra library
def mg():
    return merge(a,b)

# @Divakar's example (range enlarged)
a = np.sort(np.random.randint(0,100000000,(1000000)))
b = np.sort(np.random.randint(0,100000000,(1000000)))

timeit(so,number=10)
# 1.5669178580283187
timeit(ts,number=10)
# 0.12706473504658788
timeit(mg,number=10)
# 0.12382328097010031

# for comparison @Divakar's solution
timeit(lambda:merge_sorted_arrays(a,b),number=10)
# 0.5367169310338795

# non integer example
a = np.sort(np.random.random(1000000))
b = np.sort(np.random.random(1000000))

timeit(so,number=10)
# 1.7868053679703735
timeit(ts,number=10)
# 0.17676723399199545
timeit(mg,number=10)
# 0.1376464170170948

# and @Divakar
timeit(lambda:merge_sorted_arrays(a,b),number=10)
# 0.5656043770140968