我想检查一系列 N 整数的numpy向量是lexicographically ordered。序列中的所有向量都具有1×2的形状。( N 的值很大,所以如果它已经排序,我想避免对这个序列进行排序。)
Python或numpy是否已提供谓词来执行此类测试?
(自行推出并不难,但我更喜欢使用内置工具。)
答案 0 :(得分:1)
您可以使用np.diff和np.any:
A = np.array([[1,2,3], [2,3,1], [3, 4, 5]])
diff = np.diff(A, axis=0)
print np.all(diff>=0, axis=0)
答案 1 :(得分:1)
要拥有issorted
谓词,您需要一个明确定义的排序,或者至少是一种比较项目的明确方法。
关注我的数据性质问题。听起来好像你有这样的东西:
In [130]: x=[[1,3],[3,4],[1,2],[3,1],[0,2],[6,5]]
In [131]: x1=[np.array(i).reshape(1,2) for i in x]
In [132]: x1
Out[132]:
[array([[1, 3]]),
array([[3, 4]]),
array([[1, 2]]),
array([[3, 1]]),
array([[0, 2]]),
array([[6, 5]])]
Python排序是词法 - 也就是说,是子列表中的第一个元素,然后是第二个元素。
In [137]: sorted(x)
Out[137]: [[0, 2], [1, 2], [1, 3], [3, 1], [3, 4], [6, 5]]
numpy
排序不保留对 - 取决于按列排序的axis
规范,或行(或平面)。但是np.sort
doc确实说复数是按字母顺序排序的:
In [157]: xj = np.dot(x,[1,1j])
In [158]: xj
Out[158]: array([ 1.+3.j, 3.+4.j, 1.+2.j, 3.+1.j, 0.+2.j, 6.+5.j])
In [159]: np.sort(xj)
Out[159]: array([ 0.+2.j, 1.+2.j, 1.+3.j, 3.+1.j, 3.+4.j, 6.+5.j])
这匹配Python列表排序。
如果我对您的数据类型的猜测是正确的,那么基于比较的测试将使用如下内容:
In [167]: [i.__lt__(j) for i,j in zip(x[:-1],x[1:])]
Out[167]: [True, False, True, False, True]
In [168]: xs=sorted(x)
In [169]: [i.__lt__(j) for i,j in zip(xs[:-1],xs[1:])]
Out[169]: [True, True, True, True, True]
这也适用于复杂数组:
In [173]: xjs=np.sort(xj)
In [174]: [i.__lt__(j) for i,j in zip(xjs[:-1],xjs[1:])]
Out[174]: [True, True, True, True, True]
对于大型列表,我尝试使用其中一个itertools
进行短路迭代。
但是当应用于(普通)数组时,显然它是否已排序的问题需要进一步说明。
In [172]: [i.__lt__(j) for i,j in zip(x1[:-1],x1[1:])]
Out[172]:
[array([[ True, True]], dtype=bool),
array([[False, False]], dtype=bool),
array([[ True, False]], dtype=bool),
array([[False, True]], dtype=bool),
array([[ True, True]], dtype=bool)]
顺便说一下,(2,1)数组的列表看起来像这样:
[np.array(i).reshape(1,2) for i in x]
[array([[1, 3]]),
array([[3, 4]]),
array([[1, 2]]),
array([[3, 1]]),
array([[0, 2]]),
array([[6, 5]])]
如果变成数组则会有(6,1,2)
形状。或者你想要一个(6,2)
数组?
In [179]: np.array(x)
Out[179]:
array([[1, 3],
[3, 4],
[1, 2],
[3, 1],
[0, 2],
[6, 5]])
答案 2 :(得分:1)
numpy有 lexsort ,但这是一种排序,而不是对数据是否排序的测试。尽管如此,在排序数据上运行它的速度大约是未排序数据的两倍。
import numpy as np
import timeit
def data(N):
return np.random.randint(0,10,(N,2))
def get_sorted(x):
return x[np.lexsort(x.T)]
x = data(5)
y = get_sorted(x)
print x # to verify lex sorting
print
print y
print
x = data(1000)
y = get_sorted(x)
# to test the time for sorted vs unsorted data
print timeit.timeit("np.lexsort(x.T)", "from __main__ import np, x", number=1000)
print timeit.timeit("np.lexsort(y.T)", "from __main__ import np, y", number=1000)
以下是结果:
[[6 7] # unsorted
[4 3]
[6 7]
[9 2]
[7 3]]
[[9 2] # sorted by the second column first
[4 3]
[7 3]
[6 7]
[6 7]]
0.0788 # time to lex sort 1000x2 unsorted data values
0.0381 # time to lex sort 1000x2 pre-sorted data values
另请注意,python与numpy的速度将取决于列表,因为python有时会短路其测试。因此,如果您认为您的列表通常是未排序的,那么纯python解决方案可以在前几个值中解决这个问题,这可能要快得多;而numpy解决方案通常适用于整个阵列。