我有两个列表列表 (Python),我正在寻找最快的方法来比较这两个列表(列表)并创建一个数组(有两列)。例如,两个列表(A 和B)可以是这样的:
A = [[0, 1, 3, 6], [3, 7], [0, 1, 2], [3]]
B = [[0, 0, 0, 0], [1, 1], [2, 2, 2], [3]]
列表 A 和 B 始终具有完全相同的形状。比较之后,我希望随后的数组(比如 C)采用 A 和 B 的相应元素并形成一对数组(A 的第一个元素和 B 的第二个元素)。例如,这里 C 将是
C = np.array( [ [0,0], [1,0], [3,0], [6,0], [3,1], [7,1], [0,2], [1,2]
[2,2], [3,3] ] )
如果可能,我还想删除自身对(如 [0,0] 和 [2,2] )。
目前,我正在以列表的形式实现它(当我必须处理具有数百万行的庞大数据集时,这不是很快)。这是我目前正在使用的用于创建列表的代码:
C_list = map(lambda x, y : zip(x,y), A, B)
C_list = [item for sublist in C_list for item in sublist]
并且,为了删除自身对,我使用以下代码段:
C_list = [(x, y) for x, y in C_list if x != y]
我正在寻找一种快速的方法来实现这一点,我将非常感谢任何帮助。
最佳答案
您的代码将比必要的慢,因为您要多次具体化巨大的列表来进行数据转换。您应该使用惰性构造来设置它。在 Python 2 上,您必须将 map
替换为 itertools.imap
并将 zip
替换为 itertools.izip
。牢记这一点,这是一种我认为应该更快的 Python 3 方法,因为您通过使用 np.fromiter
直接从惰性迭代器实现数组,使用 EDIT 实际上,你不能使用 count
参数来预分配数组而不是按需调整大小count
因为你不会提前知道你过滤掉了多少项目,这是我的愚蠢错误:
>>> import itertools
>>> zipped = zip(itertools.chain.from_iterable(A), itertools.chain.from_iterable(B))
>>> it = (e for t in zipped if t[0] != t[1] for e in t)
>>> arr = np.fromiter(it, dtype=int).reshape(-1, 2)
>>> arr
array([[1, 0],
[3, 0],
[6, 0],
[3, 1],
[7, 1],
[0, 2],
[1, 2]])
>>>
至少,这将更多的内存效率。
关于Python:比较列表和创建数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42828379/