我想爲numpy實施itertools.combinations。基於this discussion,我有一維輸入工作的功能:numpy中的itertools.combinations的N-D版本
def combs(a, r):
"""
Return successive r-length combinations of elements in the array a.
Should produce the same output as array(list(combinations(a, r))), but
faster.
"""
a = asarray(a)
dt = dtype([('', a.dtype)]*r)
b = fromiter(combinations(a, r), dt)
return b.view(a.dtype).reshape(-1, r)
和輸出是有道理的:
In [1]: list(combinations([1,2,3], 2))
Out[1]: [(1, 2), (1, 3), (2, 3)]
In [2]: array(list(combinations([1,2,3], 2)))
Out[2]:
array([[1, 2],
[1, 3],
[2, 3]])
In [3]: combs([1,2,3], 2)
Out[3]:
array([[1, 2],
[1, 3],
[2, 3]])
但是
,這將是最好的,如果我可以把它擴大到ND的輸入,其中其他維度僅允許您一次快速執行多個呼叫。因此,在概念上,如果combs([1, 2, 3], 2)
產生[1, 2], [1, 3], [2, 3]
,並且combs([4, 5, 6], 2)
產生[4, 5], [4, 6], [5, 6]
,則combs((1,2,3) and (4,5,6), 2)
應該產生[1, 2], [1, 3], [2, 3] and [4, 5], [4, 6], [5, 6]
,其中「和」僅表示並行行或列(無論哪一個是有意義的)。 (並且對於其他維度)
我不知道:
- 如何使尺寸在與方式等功能的工作(如一致的一些numpy的功能如何有一個
axis=
邏輯工作方式參數和軸0的默認值。那麼可能軸0應該是我合併的軸,而所有其他軸只代表並行計算?) - 如何讓上述代碼與ND一起工作(現在我得到
ValueError: setting an array element with a sequence.
) - 有沒有更好的方法來做
dt = dtype([('', a.dtype)]*r)
?
因此'np.dtype([('',np.intp)] * r)'是創建列表dtype的「正確」方式嗎?我只是有點刺傷它,直到它工作。 – endolith
非常酷!我發現這比@ HYRY的解決方案性能稍差(在速度和內存方面),但它比剛開始使用itertools.combinations更好。 –