itertools 组合在嵌套的 np.array 中解析

itertools combinations parse in nested np.array

提问人:chowx054 提问时间:10/24/2023 更新时间:10/24/2023 访问量:68

问:

我尝试在np.array或嵌套数组中解析,并遇到了维度问题。itertools.combinations_with_replacement()

Current code only work for 1-d np.array:

X = np.array([1,2,3])  # Input

Xa = X.tolist()  # Convert to list
C = list(itertools.combinations_with_replacement(Xa, 2))
print(C) 

out= []
for j in range(len(C)):       
            out.append(np.prod(C[j]))

print(out)

# [(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]
# [1, 2, 3, 4, 6, 9]

但是,对于具有相似维度数据行的二维或嵌套数组,我很难让它工作。

# Input:
X = np.array([[1,2,3], [4,5,6],...])   # e.g., X.shape = (100, 3)


# Ideally, I would like to get an output for each row like below, 
# then multiply each tuple() within the list and compile into another np.array:

[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)] ---> [1, 2, 3, 4, 6, 9]
[(4, 4), (4, 5), (4, 6), (5, 5), (5, 6), (6, 6)] ---> [16, 20, 24, 25, 30, 36]
[....]


# Final output:
out = np.array([[1, 2, 3, 4, 6, 9], [16, 20, 24, 25, 30, 36]...])

我已经尝试过等等,但仍然被困在:(np.stack()

麻木 python-itertools

评论


答:

2赞 Julien 10/24/2023 #1

只是这个?

X = np.array([[1,2,3], [4,5,6]])

np.array([[np.prod(c) for c in combinations_with_replacement(row, 2)] for row in X])

或(更快)

np.prod([list(combinations_with_replacement(row, 2)) for row in X], axis=-1)

评论

0赞 chowx054 10/25/2023
谢谢你,朱利安。这行得通!但是,如果我需要运行...循环附加不同顺序的组合?例如,我正在寻找的最终结果将是使用 “1”, “2”....“d” 的输入 np.array 的组合: for i in range(1, d+1): Xa = np.array([[np.prod(c) for c in itertools.combinations_with_replacement(row, i)] for row in X])
1赞 Julien 10/25/2023
np.hstack([[[np.prod(c) for c in combinations_with_replacement(row, i)] for row in X] for i in range(1, d+1)])?
0赞 chowx054 10/25/2023
是的。这解决了循环问题。我为没有说得更清楚而道歉。这个问题需要多个步骤,我希望自己能弄清楚剩下的问题。非常感谢,现在我知道单行循环是如何如此强大的!
0赞 Julien 10/25/2023
PS:另一种方式:np.array([[np.prod(c) for i in range(1, d+1) for c in combinations_with_replacement(row, i)] for row in X ])
2赞 Corralien 10/24/2023 #2

您可以执行以下操作:

# Dimension=(M, N)
X = np.array([[1,2,3], [4,5,6], [7,8,9], [10,11,12]])

# Use numpy broadcasting, Dimension=(M, N, N)
A = X[:, None, :] * X[:, :, None]

# Extract the upper triangle, Dimension=(M, N)
out = A[(slice(None), *np.triu_indices(A.shape[-1]))]

# More understandable?
# idx = np.triu_indices(A.shape[-1])
# out = A[:, idx[0], idx[1]]

输出:

>>> out
array([[  1,   2,   3,   4,   6,   9],
       [ 16,  20,  24,  25,  30,  36],
       [ 49,  56,  63,  64,  72,  81],
       [100, 110, 120, 121, 132, 144]])

>>> A
array([[[  1,   2,   3],
        [  2,   4,   6],
        [  3,   6,   9]],

       [[ 16,  20,  24],
        [ 20,  25,  30],
        [ 24,  30,  36]],

       [[ 49,  56,  63],
        [ 56,  64,  72],
        [ 63,  72,  81]],

       [[100, 110, 120],
        [110, 121, 132],
        [120, 132, 144]]])

>>> X
array([[ 1,  2,  3],
       [ 4,  5,  6],
       [ 7,  8,  9],
       [10, 11, 12]])

评论

0赞 Julien 10/24/2023
Nice! Faster than my solution.... +1
0赞 Julien 10/24/2023
Although not as easily generalizable to combinations of more than 2 elements if OP cared?
0赞 Corralien 10/24/2023
I agree with you on this point. Probably can be better.sliding_window_view
0赞 chowx054 10/25/2023
Great. Thank you. This is a genius solution! Unfortunately though, i'm working on a problem with potential higher elements (i.e., greater than 2). I do appreciate your time and effort!