Python:比较列表并创建数组

Python:比较列表并创建数组,python,arrays,list,Python,Arrays,List,我有两个列表(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.a

我有两个列表(Python),我正在寻找比较这两个列表(列表)并创建一个数组(有两列)的最快的方法。例如,两个列表(AB)可以如下所示:

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]

我正在寻找一种快速的方法来实现这一点,我将非常感谢您的帮助。

您的代码将比需要的速度慢,因为您需要多次具体化庞大的列表来进行数据转换。您应该使用惰性构造进行设置。在Python2上,必须用
itertools.imap
替换
map
,用
itertools.izip
替换
zip
。记住这一点,这里有一个Python 3方法,我认为应该更快一些,因为您使用
np进行一次传递。fromiter
直接从惰性迭代器具体化数组,使用
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]])
>>>

至少,这将大大提高内存效率。

您的代码将比需要的慢,因为您要多次具体化庞大的列表以进行数据转换。您应该使用惰性构造进行设置。在Python2上,必须用
itertools.imap
替换
map
,用
itertools.izip
替换
zip
。记住这一点,这里有一个Python 3方法,我认为应该更快一些,因为您使用
np进行一次传递。fromiter
直接从惰性迭代器具体化数组,使用
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代码应该是
C_list=[item for item in zip((a for l in a for a in a for a in l),(b for l in b for b in b for b in l))if item!=item[::-1]
,但这似乎比添加所需过滤器后所需的时间长15%,如果可能的话,使用Numpy方法几乎肯定会更快(例如,我很确定有一个
flatte()
)。使用
Numpy
会很棘手,因为数据是不均匀的,看起来像是最干净的纯Python代码,因为它将是
C_list=[zip中的项对项((a代表l,a代表l中的a),(b表示l中的b表示l中的b)if item!=item[::-1]
,但这看起来比添加所需过滤器后所需的时间长15%,如果可能的话,几乎可以肯定使用Numpy方法会更快(例如,我非常确定有一个
展平()
)。使用
numpy
会很棘手,因为数据是inhomogeneous@SiddTheKid因此,我推测这实际上是您在数据上尝试它的时候?非常感谢您的回答!代码中是否有错误,因为arr还应该包含[0,2]和[1,2]对除了它已经包含的那些之外?如果我能知道两种不同的技术(一种是保留自对,另一种是删除自对。顺便说一句,它确实使代码的内存效率更高。=)如果一个通过count*2,同时在后面加上“it=(e代表t,zipped代表e代表t)”的话“arr=np.fromiter(it,count=2*count,dtype=int)。重塑(-1,2)”则没有错误,但可以获得包括自对在内的所有对。如何使用此选项并删除自对?当我使用“it=(t=t,如果t[0]!=t[1]表示t中的e)”后跟“arr=np.fromiter(it,count=2*count,dtype=int)时,会出现错误(迭代器太短).Reformate(-1,2)”。我真的很感谢你的帮助。@SiddTheKid是的,刚想出来,编辑了答案。不幸的是,你不能使用
count
@juanpa.arrivillaga:我想起来了。那么,有没有办法解决这个问题(在删除自对的同时)?通过修改你的方法,我能够解决另一个问题(在拥有自配对的情况下加快代码速度)。=@SiddTheKid那么,我想这实际上是您在数据上尝试它时的结果?非常感谢您的回答!代码中是否有错误,因为arr还应该包含[0,2]和[1,2]对除了它已经包含的那些之外?如果我能知道两种不同的技术(一种是保留自对,另一种是删除自对。顺便说一句,它确实使代码的内存效率更高。=)如果一个通过count*2,同时在后面加上“it=(e代表t,zipped代表e代表t)”和arr=np.fromiter(it,count=2*count,dtype=int)。重塑(-1,2)”则没有错误,但可以获得包括自对在内的所有对。如何使用此选项并删除自对?当我使用“it=(t[0]时压缩的t中的e)!=t[1]后接“arr=np.fromiter(it,count=2*count,dtype=int)时,会出现错误(迭代器太短).Reforme(-1,2)”。我真的很感谢你的帮助。@SiddTheKid yeah刚想出来,正在编辑答案。不幸的是,你不能使用
count
@jua