我有兩個 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) 做得更好?
uj5u.com熱心網友回復:
首先,您顯示兩個串列,但稱它們為陣列。
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()被編譯并且相對較快,但是對于足夠大的陣列仍然需要時間。
總而言之——如果你從串列開始,然后回傳一個串列,那么純串列方法仍然是最好的。但是以陣列開始和結束可能會更快。混合串列和陣列都會減慢速度。
使用已接受答案中的映射:
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)
uj5u.com熱心網友回復:
你可以在 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)]
uj5u.com熱心網友回復:
您可以將它們轉換為 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]]
uj5u.com熱心網友回復:
替代方案,僅限 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]]
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/428059.html
標籤:Python 麻木的 python-2.7
