【问题标题】:Python vectorization, how to get all index for every row with numpyPython矢量化,如何使用numpy获取每一行的所有索引
【发布时间】:2019-06-18 19:44:36
【问题描述】:

我很难解决这个问题,主要问题是我正在运行模拟,所以主要禁止 lops,我有一个 numpy 数组 NxN,在这种情况下我的大约是 (10000x20) .

stoploss = 19.9 # condition to apply
monte_carlo_simulation(20,1.08,10000,20) #which gives me that 10000x20 np array
mask_trues = np.where(np.any((simulation <= stoploss) == True, axis=1)) # boolean mask

我需要一些代码来创建一个新的 len(10000) 向量,它返回一个包含每一行所有位置的数组,假设:

function([[False,True,True],[False,False,True]])
output = [[1,2],[2]]

同样,主要问题在于不使用循环。

【问题讨论】:

  • 所以output 将是一个包含不同长度列表的列表。这将需要某种行迭代,即使它被埋在split
  • 你真的需要按行索引吗? (100000, 20) 布尔值有什么问题?您可以轻松地从掩码中获取行数(总和)。要使用列表列表,您必须进行迭代。该掩码也可以转换为scipy.sparse 矩阵。 lil 格式 rows 数组将是所需的“非零”列索引数组。
  • 嗨 hpaulj,我需要准确的位置,因为我必须将每个位置与买入价和卖出价进行比较,我会丢失数据,只是计算它发生的次数或每次获得第一个排。我来自西班牙,所以凌晨 2 点我正在寻找一种有效的解决方案,而不是免费的迭代解决方案。
  • 为什么要标记模拟?数据来源似乎与您的问题无关。我是否错过了一些相关的方式?
  • 嗨 pjs,我标记它是因为这确实是模拟的一部分。不过我理解你的意思,我保证下次使用标签字段时会更准确。

标签: python python-3.x numpy vectorization simulation


【解决方案1】:

简单地说:

list(map(np.where, my_array))

与 Kasrâmvd 解决方案的性能比较:

def f(a):
    return list(map(np.where, a))

def g(a):
    x, y = np.where(a)
    return np.split(y, np.where(np.diff(x) != 0)[0] + 1)

a = np.random.randint(2, size=(10000,20))

%timeit f(a)
%timeit g(a)


7.66 ms ± 38.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
13.3 ms ± 188 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

【讨论】:

    【解决方案2】:

    为了完整起见,我将演示一个稀疏矩阵方法:

    In [57]: A = np.array([[False,True,True],[False,False,True]])
    In [58]: A
    Out[58]: 
    array([[False,  True,  True],
           [False, False,  True]])
    In [59]: M = sparse.lil_matrix(A)
    In [60]: M
    Out[60]: 
    <2x3 sparse matrix of type '<class 'numpy.bool_'>'
        with 3 stored elements in LInked List format>
    In [61]: M.data
    Out[61]: array([list([True, True]), list([True])], dtype=object)
    In [62]: M.rows
    Out[62]: array([list([1, 2]), list([2])], dtype=object)
    

    并制作一个大的稀疏:

    In [63]: BM = sparse.random(10000,20,.05, 'lil')
    In [64]: BM
    Out[64]: 
    <10000x20 sparse matrix of type '<class 'numpy.float64'>'
        with 10000 stored elements in LInked List format>
    In [65]: BM.rows
    Out[65]: 
    array([list([3]), list([]), list([6, 15]), ..., list([]), list([11]),
           list([])], dtype=object)
    

    粗略时间测试:

    In [66]: arr = BM.A
    In [67]: timeit sparse.lil_matrix(arr)
    19.5 ms ± 421 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    In [68]: timeit list(map(np.where,arr))
    11 ms ± 55.6 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    In [69]: %%timeit
        ...: x,y = np.where(arr)
        ...: np.split(y, np.where(np.diff(x) != 0)[0] + 1)
        ...: 
    13.8 ms ± 24.3 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    

    生成csr 稀疏格式矩阵更快:

    In [70]: timeit sparse.csr_matrix(arr)
    2.68 ms ± 120 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    
    In [71]: Mr = sparse.csr_matrix(arr)
    In [72]: Mr.indices
    Out[72]: array([ 3,  6, 15, ...,  8, 16, 11], dtype=int32)
    In [73]: Mr.indptr
    Out[73]: array([    0,     1,     1, ...,  9999, 10000, 10000], dtype=int32)
    In [74]: np.where(arr)[1]
    Out[74]: array([ 3,  6, 15, ...,  8, 16, 11])
    

    indices 就像列 where,而 indptr 就像 split indices

    【讨论】:

      【解决方案3】:

      这是使用np.split()np.diff() 的一种方法:

      x, y = np.where(boolean_array)
      np.split(y, np.where(np.diff(x) != 0)[0] + 1)
      

      演示:

      In [12]: a = np.array([[False,True,True],[False,False,True]])
      
      In [13]: x, y = np.where(a)
      
      In [14]: np.split(y, np.where(np.diff(x) != 0)[0] + 1)
      Out[14]: [array([1, 2]), array([2])]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-09-06
        • 2021-06-30
        • 1970-01-01
        • 2021-05-07
        • 2011-10-16
        • 2016-11-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多