日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python索引 自定义_python – 使用多个自定义索引范围构建numpy数组,而不显式循环...

發布時間:2023/12/3 python 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python索引 自定义_python – 使用多个自定义索引范围构建numpy数组,而不显式循环... 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在Numpy中,是否有一種pythonic方法來創建array3,其中自定義范圍來自array1和array2而沒有循環?迭代范圍的直接解決方案有效,但由于我的數組遇到了數百萬個項目,我正在尋找更有效的解決方案(也可能是語法糖).

例如,

array1 = np.array([10, 65, 200])

array2 = np.array([14, 70, 204])

array3 = np.concatenate([np.arange(array1[i], array2[i]) for i in

np.arange(0,len(array1))])

print array3

結果:[10,11,12,13,65,66,67,68,69,200,201,202,203].

解決方法:

前瞻性方法

我將回顧如何解決這個問題.

采取問題中列出的樣本.我們有 –

array1 = np.array([10, 65, 200])

array2 = np.array([14, 70, 204])

現在,看看想要的結果 –

result: [10,11,12,13,65,66,67,68,69,200,201,202,203]

讓我們計算組長度,因為我們需要那些解釋下一步的解決方案.

In [58]: lens = array2 - array1

In [59]: lens

Out[59]: array([4, 5, 4])

我們的想法是使用1的初始化數組,當在整個長度上進行累積求和時,可以得到所需的結果.

這個累積總和將是我們解決方案的最后一步.

為什么1的初始化?好吧,因為我們有一個數組以1的步長增加,除了在我們有變化的特定地方

對應新的團體進來.

現在,因為cumsum將是最后一步,所以它之前的步驟應該給我們一些像 –

array([ 10, 1, 1, 1, 52, 1, 1, 1, 1, 131, 1, 1, 1])

正如前面所討論的那樣,在特定的地方,它的1是[10,52,131].那個10似乎是從array1中的第一個元素進來的,但其余的呢?

第二個52以65-13(看結果)進入,其中13個進入了以10開頭并且因為長度而跑的組

第一組4.所以,如果我們做65 – 10 – 4,我們將獲得51然后加1以適應邊界停止,我們將有52,這是

期望的轉移價值.同樣,我們會得到131.

因此,可以像這樣計算那些移位值 –

In [62]: np.diff(array1) - lens[:-1]+1

Out[62]: array([ 52, 131])

接下來,為了獲得發生這種轉變的那些轉移位置,我們可以簡單地對組長度進行累積求和 –

In [65]: lens[:-1].cumsum()

Out[65]: array([4, 9])

為了完整性,我們需要為移位值預先附加0,使用array1 [0]作為移位值.

因此,我們將逐步展示我們的方法!

把它們放回去

1]獲取每組的長度:

lens = array2 - array1

2]獲取發生偏移的索引和要放入1的初始化數組中的值:

shift_idx = np.hstack((0,lens[:-1].cumsum()))

shift_vals = np.hstack((array1[0],np.diff(array1) - lens[:-1]+1))

3] Setup 1的初始化ID數組,用于將這些值插入前面步驟中列出的那些索引:

id_arr = np.ones(lens.sum(),dtype=array1.dtype)

id_arr[shift_idx] = shift_vals

4]最后對ID數組進行累加求和:

output = id_arr.cumsum()

以功能格式列出,我們會 –

def using_ones_cumsum(array1, array2):

lens = array2 - array1

shift_idx = np.hstack((0,lens[:-1].cumsum()))

shift_vals = np.hstack((array1[0],np.diff(array1) - lens[:-1]+1))

id_arr = np.ones(lens.sum(),dtype=array1.dtype)

id_arr[shift_idx] = shift_vals

return id_arr.cumsum()

它也適用于重疊范圍!

In [67]: array1 = np.array([10, 11, 200])

...: array2 = np.array([14, 18, 204])

...:

In [68]: using_ones_cumsum(array1, array2)

Out[68]:

array([ 10, 11, 12, 13, 11, 12, 13, 14, 15, 16, 17, 200, 201,

202, 203])

運行時測試

讓我們來討論@unutbu's flatnonzero based solution中針對其他矢量化方法的提議方法,這種方法已經證明比循環方法好得多 –

In [38]: array1, array2 = (np.random.choice(range(1, 11), size=10**4, replace=True)

...: .cumsum().reshape(2, -1, order='F'))

In [39]: %timeit using_flatnonzero(array1, array2)

1000 loops, best of 3: 889 μs per loop

In [40]: %timeit using_ones_cumsum(array1, array2)

1000 loops, best of 3: 235 μs per loop

改進!

現在,代碼NumPy不喜歡追加.因此,對于稍微改進的版本,可以避免那些np.hstack調用,如下所示 –

def get_ranges_arr(starts,ends):

counts = ends - starts

counts_csum = counts.cumsum()

id_arr = np.ones(counts_csum[-1],dtype=int)

id_arr[0] = starts[0]

id_arr[counts_csum[:-1]] = starts[1:] - ends[:-1] + 1

return id_arr.cumsum()

讓我們反對我們原來的做法 –

In [151]: array1,array2 = (np.random.choice(range(1, 11),size=10**4, replace=True)\

...: .cumsum().reshape(2, -1, order='F'))

In [152]: %timeit using_ones_cumsum(array1, array2)

1000 loops, best of 3: 276 μs per loop

In [153]: %timeit get_ranges_arr(array1, array2)

10000 loops, best of 3: 193 μs per loop

所以,我們的性能提升了30%!

標簽:python,arrays,vectorization,numpy,performance

來源: https://codeday.me/bug/20190611/1219579.html

總結

以上是生活随笔為你收集整理的python索引 自定义_python – 使用多个自定义索引范围构建numpy数组,而不显式循环...的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。