如何将 N 维 numpy 数组按元素转换为列表
How to convert N-D numpy arrays element-wise to list
我有两个 numpy 数组:
A = [[1,2,3],
[4,5,6]]
B = [[-1,-2,-3],
[-4,-5,-6]]
我想将两者组合成一个普通的 python 列表,这样每个数组中的 (i,j) 元素都放在同一个列表中:
C= [[1,-1],[2,-2],[3,-3],[4,-4],[5,-5],[6,-6]]
有没有比天真的 O(n^2) 更好的方法?
您可以在 O(n) 中完成:
A = np.array([[1,2,3],
[4,5,6]])
B = np.array([[-1,-2,-3],
[-4,-5,-6]])
C = list(map(list, zip(A.ravel(), B.ravel())))
输出:
[[1, -1], [2, -2], [3, -3], [4, -4], [5, -5], [6, -6]]
如果您不介意元组:
C = list(zip(A.ravel(), B.ravel()))
输出:
[(1, -1), (2, -2), (3, -3), (4, -4), (5, -5), (6, -6)]
您可以将它们转换为 np.array、重塑和转置:
out = np.array([A,B]).reshape(2,-1).T.tolist()
或遍历子列表并使用 zip
:
out = [list(tpl) for i in range(len(A)) for tpl in zip(A[i], B[i])]
输出:
[[1, -1], [2, -2], [3, -3], [4, -4], [5, -5], [6, -6]]
备选方案,仅限 NumPy,已接受答案的解决方案:
A = np.array([[1,2,3],
[4,5,6]])
B = np.array([[-1,-2,-3],
[-4,-5,-6]])
C = np.column_stack((A.ravel(),B.ravel())).tolist()
输出:
[[1, -1], [2, -2], [3, -3], [4, -4], [5, -5], [6, -6]]
首先,您显示两个列表,但称它们为数组。
In [102]: A = [[1,2,3],
...: [4,5,6]]
...: B = [[-1,-2,-3],
...: [-4,-5,-6]]
纯数组方法的一个版本:
In [103]: [[i,j] for a,b in zip(A,B) for i,j in zip(a,b)]
Out[103]: [[1, -1], [2, -2], [3, -3], [4, -4], [5, -5], [6, -6]]
还有一种 numpy 方法 - 这适用于列表或数组,因为 np.stack
根据需要将列表转换为数组。
In [104]: np.stack((A,B),axis=2).reshape(-1,2).tolist()
Out[104]: [[1, -1], [2, -2], [3, -3], [4, -4], [5, -5], [6, -6]]
np.array((A,B))
也可以使用,但需要一些转置;但这很便宜。
O(n) 分析在评估此类备选方案时没那么有用。最大的区别是在 python 中迭代,就像双列表理解那样,或者使用 numpy 数组方法(在编译代码中迭代)。但这也有细微差别。数组的迭代速度较慢。从列表创建数组需要时间。还有一个缩放问题。数组方法通常具有较高的设置成本,但扩展性更好。
让我们比较一下时间:
In [105]: timeit [[i,j] for a,b in zip(A,B) for i,j in zip(a,b)]
1.69 µs ± 29.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [106]: timeit np.stack((A,B),axis=2).reshape(-1,2).tolist()
22.2 µs ± 1.37 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [107]: %%timeit A1=np.array(A); B1=np.array(B)
...: np.stack((A1,B1),axis=2).reshape(-1,2).tolist()
14.5 µs ± 65.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
对于这个小例子,纯列表方法是最快的。从数组而不是列表开始改进了数组方法,但它仍然较慢。
尝试更大的东西:
In [109]: AA = np.ones((200,300)).tolist()
In [110]: timeit [[i,j] for a,b in zip(AA,AA) for i,j in zip(a,b)]
10.4 ms ± 19.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [111]: %%timeit A1=np.array(AA); B1=np.array(AA)
...: np.stack((A1,B1),axis=2).reshape(-1,2).tolist()
13.4 ms ± 334 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
仍然不足以让阵列发挥优势。
但是如果我们放弃结果是列表的要求呢?
In [119]: %%timeit A1=np.array(AA); B1=np.array(AA)
...: np.stack((A1,B1),axis=2).reshape(-1,2)
144 µs ± 4.78 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
tolist()
已编译且相对较快,但对于足够大的数组来说仍然需要时间。
总而言之 - 如果您从列表开始,return 一个列表,那么纯列表方法仍然是最好的。但是以数组开始和结束可以更快。混合列表和数组会降低两者的速度。
接受答案中的映射:
In [120]: %%timeit A1=np.array(AA); B1=np.array(AA)
...: C = list(map(list, zip(A1.ravel(), B1.ravel())))
16.2 ms ± 44.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我有两个 numpy 数组:
A = [[1,2,3],
[4,5,6]]
B = [[-1,-2,-3],
[-4,-5,-6]]
我想将两者组合成一个普通的 python 列表,这样每个数组中的 (i,j) 元素都放在同一个列表中:
C= [[1,-1],[2,-2],[3,-3],[4,-4],[5,-5],[6,-6]]
有没有比天真的 O(n^2) 更好的方法?
您可以在 O(n) 中完成:
A = np.array([[1,2,3],
[4,5,6]])
B = np.array([[-1,-2,-3],
[-4,-5,-6]])
C = list(map(list, zip(A.ravel(), B.ravel())))
输出:
[[1, -1], [2, -2], [3, -3], [4, -4], [5, -5], [6, -6]]
如果您不介意元组:
C = list(zip(A.ravel(), B.ravel()))
输出:
[(1, -1), (2, -2), (3, -3), (4, -4), (5, -5), (6, -6)]
您可以将它们转换为 np.array、重塑和转置:
out = np.array([A,B]).reshape(2,-1).T.tolist()
或遍历子列表并使用 zip
:
out = [list(tpl) for i in range(len(A)) for tpl in zip(A[i], B[i])]
输出:
[[1, -1], [2, -2], [3, -3], [4, -4], [5, -5], [6, -6]]
备选方案,仅限 NumPy,已接受答案的解决方案:
A = np.array([[1,2,3],
[4,5,6]])
B = np.array([[-1,-2,-3],
[-4,-5,-6]])
C = np.column_stack((A.ravel(),B.ravel())).tolist()
输出:
[[1, -1], [2, -2], [3, -3], [4, -4], [5, -5], [6, -6]]
首先,您显示两个列表,但称它们为数组。
In [102]: A = [[1,2,3],
...: [4,5,6]]
...: B = [[-1,-2,-3],
...: [-4,-5,-6]]
纯数组方法的一个版本:
In [103]: [[i,j] for a,b in zip(A,B) for i,j in zip(a,b)]
Out[103]: [[1, -1], [2, -2], [3, -3], [4, -4], [5, -5], [6, -6]]
还有一种 numpy 方法 - 这适用于列表或数组,因为 np.stack
根据需要将列表转换为数组。
In [104]: np.stack((A,B),axis=2).reshape(-1,2).tolist()
Out[104]: [[1, -1], [2, -2], [3, -3], [4, -4], [5, -5], [6, -6]]
np.array((A,B))
也可以使用,但需要一些转置;但这很便宜。
O(n) 分析在评估此类备选方案时没那么有用。最大的区别是在 python 中迭代,就像双列表理解那样,或者使用 numpy 数组方法(在编译代码中迭代)。但这也有细微差别。数组的迭代速度较慢。从列表创建数组需要时间。还有一个缩放问题。数组方法通常具有较高的设置成本,但扩展性更好。
让我们比较一下时间:
In [105]: timeit [[i,j] for a,b in zip(A,B) for i,j in zip(a,b)]
1.69 µs ± 29.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
In [106]: timeit np.stack((A,B),axis=2).reshape(-1,2).tolist()
22.2 µs ± 1.37 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
In [107]: %%timeit A1=np.array(A); B1=np.array(B)
...: np.stack((A1,B1),axis=2).reshape(-1,2).tolist()
14.5 µs ± 65.8 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
对于这个小例子,纯列表方法是最快的。从数组而不是列表开始改进了数组方法,但它仍然较慢。
尝试更大的东西:
In [109]: AA = np.ones((200,300)).tolist()
In [110]: timeit [[i,j] for a,b in zip(AA,AA) for i,j in zip(a,b)]
10.4 ms ± 19.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
In [111]: %%timeit A1=np.array(AA); B1=np.array(AA)
...: np.stack((A1,B1),axis=2).reshape(-1,2).tolist()
13.4 ms ± 334 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
仍然不足以让阵列发挥优势。
但是如果我们放弃结果是列表的要求呢?
In [119]: %%timeit A1=np.array(AA); B1=np.array(AA)
...: np.stack((A1,B1),axis=2).reshape(-1,2)
144 µs ± 4.78 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
tolist()
已编译且相对较快,但对于足够大的数组来说仍然需要时间。
总而言之 - 如果您从列表开始,return 一个列表,那么纯列表方法仍然是最好的。但是以数组开始和结束可以更快。混合列表和数组会降低两者的速度。
接受答案中的映射:
In [120]: %%timeit A1=np.array(AA); B1=np.array(AA)
...: C = list(map(list, zip(A1.ravel(), B1.ravel())))
16.2 ms ± 44.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)