【问题标题】:Python, Numpy: copying single rows to multiple indexes in irregular orderPython,Numpy:以不规则顺序将单行复制到多个索引
【发布时间】:2021-11-06 14:18:28
【问题描述】:

我有一个问题,我需要将一个矩阵的单行复制到更大矩阵中的多个特定行。例如:

            Matrix A:
                [row1]
                [row2]
                [row3]

复制到

            Matrix B:
                [row3]
                [row3] 
                [row2]
                [row2] 
                [row3] 
                [row1] 

A 中的值在执行过程中可能会发生变化,但行总是以相同的模式复制到 B。 我已经试过了:

            B = A[3,3,2,2,3,1]

但这比我将行逐行放置的简单 for 循环还要慢。我需要使用矩阵大小 A ≈ (500, 500) 和 B ≈ (2000, 500) 尽快完成此操作。 有谁知道使用 numpy 矩阵在 python 中执行此操作的更有效方法?

【问题讨论】:

  • 据我所知,问题的大小,即矩阵的大小和数据量非常重要。在与您编写的示例一样小的矩阵示例中,我想方法之间不会有显着差异。在SO上比较一些方法可以看出,在执行一段时间后,与方法相关的总执行时间变得比其他方法少;在总执行时间内从最差到最好。在此类问题中,我建议使用诸如 numpy 之类的库,以及更好的 jax。
  • 你的意思是,没有使用例如A.tolist() 在@sgs 的答案中使用?从B = A[3,3,2,2,3,1] 可以理解,B 中每一行的计数可以变化,即 row3 的计数不等于 row1 的计数(3 != 1)。是真的还是 A 的每一行都以相同的计数复制到 B 中?
  • 是的,B 中每个不同行的行数可能不同。我的意思是我总是将它们复制到同一个位置,B 的模式在整个执行过程中是一致的。所以 B 中某些行的计数也保持不变。只是 A 中的值发生了变化,我必须一遍又一遍地重复相同的复制过程。
  • 嗨@Archaon,如果有任何答案解决了您的问题或有帮助,请通过单击复选标记或投票来考虑accepting it。这向更广泛的社区表明您已经找到了解决方案,并为回答者和您自己提供了一些声誉。没有义务这样做。

标签: python arrays numpy matrix copy


【解决方案1】:

正如numpy documentation 中推荐的那样,最好使用数组而不是矩阵。我已经测试了以下代码来比较使用数组和矩阵:

import numpy as np
import timeit
A_arr = np.array([[1, 2], [3, 4], [5, 6]])
A_mat = np.matrix([[1, 2], [3, 4], [5, 6]])
Alist_arr = A_arr.tolist()
Alist_mat = A_mat.tolist()
# using listing
%timeit -n1000 -r5 np.array([Alist_arr[2], Alist_arr[2], Alist_arr[1], Alist_arr[1], Alist_arr[2], Alist_arr[0]])
%timeit -n1000 -r5 np.array([Alist_mat[2], Alist_mat[2], Alist_mat[1], Alist_mat[1], Alist_mat[2], Alist_mat[0]])
%timeit -n1000 -r5 np.matrix([Alist_arr[2], Alist_arr[2], Alist_arr[1], Alist_arr[1], Alist_arr[2], Alist_arr[0]])
%timeit -n1000 -r5 np.matrix([Alist_mat[2], Alist_mat[2], Alist_mat[1], Alist_mat[1], Alist_mat[2], Alist_mat[0]])
# without listing
%timeit -n1000 -r5 np.array([A_arr[2], A_arr[2], A_arr[1], A_arr[1], A_arr[2], A_arr[0]])
%timeit -n1000 -r5 np.array([np.ravel(A_mat[2]), np.ravel(A_mat[2]), np.ravel(A_mat[1]), np.ravel(A_mat[1]), np.ravel(A_mat[2]), np.ravel(A_mat[0])])
%timeit -n1000 -r5 np.matrix([A_arr[2], A_arr[2], A_arr[1], A_arr[1], A_arr[2], A_arr[0]])
%timeit -n1000 -r5 np.matrix([np.ravel(A_mat[2]), np.ravel(A_mat[2]), np.ravel(A_mat[1]), np.ravel(A_mat[1]), np.ravel(A_mat[2]), np.ravel(A_mat[0])])

并取得了以下成果:

1000 loops, best of 5: 6.99 µs per loop
1000 loops, best of 5: 7.16 µs per loop
1000 loops, best of 5: 13.2 µs per loop
1000 loops, best of 5: 13.2 µs per loop
1000 loops, best of 5: 4.32 µs per loop
1000 loops, best of 5: 38.4 µs per loop
1000 loops, best of 5: 11.8 µs per loop
1000 loops, best of 5: 48.1 µs per loop

上述结果表明,使用数组而不是矩阵而不使用列表将具有最少的执行时间。因此,我建议使用以下代码获取 B:

B = np.array([A_arr[2], A_arr[2], A_arr[1], A_arr[1], A_arr[2], A_arr[0]])

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    我不确定这是否是您正在寻找的,但它看起来相当快

    %%timeit
    A = np.matrix([[1,2],[3,4],[5,6]])
    Alist = A.tolist()  
    B = np.matrix([Alist[2],Alist[2],Alist[1],Alist[1],Alist[2],Alist[0]])
    
    
    13.4 µs ± 82.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    

    【讨论】:

    • 使用 np.array 代替 np.matrix 将时间减半。
    • OP似乎愿意使用矩阵,这就是我保留它的原因
    • 我的解释可能有点误导,当然 np.arrays 就足够了。我希望有一种不使用标准 python 列表的更快方法,但这已经有帮助了,谢谢
    猜你喜欢
    • 1970-01-01
    • 2021-11-08
    • 2023-02-01
    • 2021-03-03
    • 2015-02-20
    • 1970-01-01
    • 2021-10-24
    • 2021-07-06
    • 2018-06-10
    相关资源
    最近更新 更多