假设我有以下numpy
数组:
arr = numpy.array([[1, 7], [2, 0], [2, 1], [2, 3], [3, 4], [3, 5], [5, 6]])
假设我选择了一个特定的密钥,在本例中为2
。然后我希望排序如下:
arr_sorted = [[2, 0], [2, 1], [2, 3], [1, 7], [3, 4], [3, 5], [5, 6]]
这个想法首先从键为2的所有元素开始,然后转到其键是上一个键值的条目。
从2开始,条目为[2, 0], [2, 1], [2, 3]
。因此,2之后的下一个键将是0,1,3。没有条目以0作为键。有一个条目以1为密钥:[1, 7]
。有两个条目,其中3为密钥:[3, 4], [3, 5]
。下一个未处理的密钥是7
,但它没有条目。同样适用于4.有一个条目,其中5为密钥:[5, 6]
。 6没有条目。
是否有任何numpy
或dictionary
技巧可以达到此目的?
我最接近的尝试如下:
def bfs_finder(d, start):
queue = deque([start])
seen = [start]
results = []
while queue:
_vertices = queue.popleft()
current = [i for i, a in enumerate(d) if len([x for x in a if x in _vertices])==1 and i not in seen]
curr1 = [a[1] for i, a in enumerate(d) if len([x for x in a if x in _vertices]) == 1 and i not in seen]
if len(current)>0:
results.extend(curr1)
queue.extend(curr1)
seen.extend(current)
return results
但是,我实际上收到current = [i for i, a in enumerate(d) if len([x for x in a if x in _vertices])==1 and i not in seen]
TypeError: argument of type 'int' is not iterable
的错误。任何有关如何解决此错误的建议,以及是否有任何良好的改进都将受到高度赞赏。
答案 0 :(得分:1)
您可以使用set
来保存已处理的密钥和deque
或类似的堆栈兼容容器来保存已处理的值(列表也可以使用)。由于您有numpy数组,您可以按行对数组进行预排序,并使用第一列上的np.searchsorted
从中提取条带。
算法将是这样的:
stack
排序操作是O(n log(n))
。二分算法也是如此(大约n
次搜索,每个O(log(n))
。因此,您的算法复杂度不应超过O(n log(n))
,这对于奇怪的排序算法非常有用。
根据np.argsort
使用this answer按行排序似乎最快,幸运的是np.searchsorted
接受sorter
参数。
以下是一个示例实现:
import numpy as np
from collections import deque
def bfs_finder(d, start):
sorter = np.argsort(d[:, 0])
done = set()
todo = deque([start])
output = np.empty_like(d)
pos = 0
while todo:
key = todo.popleft()
if key in done:
continue
done.add(key)
left = np.searchsorted(d[:, 0], key, 'left', sorter)
if left >= d.shape[0] or d[sorter[left], 0] != key:
continue
right = np.searchsorted(d[:, 0], key, 'right', sorter)
next = pos + right - left
output[pos:next, :] = d[sorter[left:right], :]
todo.extend(output[pos:next, 1])
pos = next
return output
arr = np.array([[1, 7], [2, 0], [2, 1], [2, 3], [3, 4], [3, 5], [5, 6]])
print(bfs_finder(arr, 2))
[[2 0]
[2 1]
[2 3]
[1 7]
[3 4]
[3 5]
[5 6]]
此解决方案假定输出中缺少原始密钥。如果遇到该问题,请从处理密钥集中减去第一列的集合,并确定如何处理剩余部分。
您可以通过将整个堆栈传递给searchsorted
的每次调用而不是一次只执行一个元素来获得额外的里程。