為自己Coding
為自己Coding

YO~~ 剛跨入AI人工智慧領域的小小工程師, 熱愛自學, 熱愛分享, 下班後的我想為自己Coding, 積極撰寫教學文, 想將自學的程式知識分享給大家, 不斷追求進步的自己, 希望有一天能回饋社會,幫助需要幫助的人, 如果您有什麼很酷的想法,也覺得我還行,歡迎您找我合作~~ IG: https://www.instagram.com/coding_4_me/

給自己的Python小筆記 - NumPy中的 searchsorted用法 - 實作數據装箱(分組)

searchsorted 函數用法 - 如何知道插入的數需要放在哪呢?

Github連結

攝影師:Gianluca Grisenti,連結:Pexels



1. Searchsorted 函數

np.searchsorted(a, v, side='left', sorter = None)

說明: 於數組a中插入數組v,但不實際插人,而是返回一個索引列表,表示V中的元素應該插在a中哪個位置

重要提醒: 預設的狀況下sorter=None,也就是a數組要為升序數組,也就是要排好從小到大的數組



2. 參數



3. 實作


構建輸入數組

## 導人NumPy套件
import numpy as np
​
## 構建一個NumPy 數組
x = np.array([0,2,8,10,14,17,19,25,29,32,36,58])
x

執行結果

array([ 0, 2, 8, 10, 14, 17, 19, 25, 29, 32, 36, 58])


1. 插人單個元素


A. 插入輸入數組中沒有的元素(介於最大與最小值之間的數)

## 插入單個元素
ind1 = np.searchsorted(x, 28)
print ('Insert 28: ', ind1)
​
## 設定side=left
ind2 = np.searchsorted(x, 28, side = 'left')
print ('Insert 28 and set side = left: ', ind2)
​
## 設定side = right
ind3 = np.searchsorted(x, 28, side = 'right')
print('Insert 28 and set side = right: ', ind3)

執行結果

Insert 28: 8
Insert 28 and set side = left: 8
Insert 28 and set side = right: 8


B. 插入比輸入數組最小值更小的元素

## 插入比輸人數組的最小值更小的元素
​
## 設定side = left
ind1 = np.searchsorted(x, -2, side = 'left')
print('Insert 28 and set side = left: ', ind1)
​
## 設定side = right
ind2 = np.searchsorted (x, -2, side = 'right')
print('Insert 28 and set side = right: ', ind2)

執行結果

Insert 28 and set side = left: 0
Insert 28 and set side = right: 0


C. 插入比輸入數組最大值更大的元素

## 插入比輸入數组最大值更大的元素
## 設定side = left
ind1 = np.searchsorted (x, 99, side = 'left')
print ('Insert 28 and set side = left: ', ind1)
​
## 設定side = right
ind2 = np.searchsorted(x, 99, side = 'right')
print('Insert 28 and set side = right: ', ind2)

執行結果

Insert 28 and set side = left: 12
Insert 28 and set side = right: 12


D. 插入值跟輸入數組裡面的元素相等

## 播入信跟輸人數组裡面的元素相等
## 設定side=left
ind1 = np.searchsorted(x, 2, side = 'left')
print ('Insert 28 and set side = left: ', ind1)
​
## 設定side = right
ind2 = np.searchsorted(x, 2, side = 'right')
print('Insert 28 and set side = right: ', ind2)
​
​
​
## 當插人值跟輸入數組裡面的元素相等, side -'left'和s ide = 'right'結果是不一樣的
## 1.side = left: 會返回與相同元素一樣的位置
## 2.side=right:會返回相同元素的下一個位置

執行結果

Insert 28 and set side = left: 1
Insert 28 and set side = right: 2


結果:當插入值跟输入數組裡面的元素相等,side = 'left'和side = 'right'結果是不一樣的

  1. side="left": 會返回與相同元素一樣的位置
  2. side="right": 會返回相同元素的下個位置



2. 插入數組

## 插入值為一個數組
## 設定side = left
ind1 = np.searchsorted(x, [-2,3,8,9,26,28,58,66], side = 'left')
print ('Insert 28 and set side = left: ', ind1)
​
## 設定side = right
ind2 = np.searchsorted(x, [-2,3,8,9, 26, 28, 58,66], side = 'right')
print('Insert 28 and set side = right:', ind2)

執行結果

Insert 28 and set side = left: [ 0 2 2 3 8 8 11 12]
Insert 28 and set side = right: [ 0 2 3 3 8 8 12 12]

結果: 返回一個數組



3. 當輸人數據沒有排好序(升序)的狀況


解決方法: 這時候就要設定sorter,透過np.argsort()找到沒有排好序的翰人數據的正確(升序)索引數組,再带進sorter就可以解決了

## 當輸入數組不是升序的狀況
## 隐機排列x數組
np.random.shuffle(x)
print ('x = ', x)
​
​
## 要先存放x的正確排序索引值
x_sort_index = np.argsort(x)
print('x_sort_index: ', x_sort_index)
​
## 接下來才能執行插人
​
## 設定side = left
ind1 = np.searchsorted (x, [-2,3,8,9,26,28, 58,66], side ='left', sorter = x_sort_index)
print('Insert 28 and set side = left: ', ind1)
​
## 設定side=right
ind2 = np.searchsorted (x, [-2,3,8,9, 26,28, 58, 66], side = 'right', sorter = x_sort_index)
print('Insert 28 and set side right: ', ind2)

執行結果

x = [29 19 10 58 2 17 14 36 25 32 0 8]
x_sort_index: [10 4 11 2 6 5 1 8 0 9 7 3]
Insert 28 and set side = left: [ 0 2 2 3 8 8 11 12]
Insert 28 and set side right: [ 0 2 3 3 8 8 12 12]



應用範例:數據裝箱(分組)

  • 舉例: 我們有1000 個值,想將它們分別放人各個不同的數組分組中,並快速地找到它們在分組數組中的位置, 此時就可以使用searchsorted()函數找到這些值應該被放人哪個箱子
import numpy as np
import matplotlib.pyplot as plt
​
## 隨機產生一個一維並擁有100個標準正態分布的值
np.random.seed(66)
x = np.random.randn(100)
​
## 自定義一個數據分組, 區間-5到5平均取20個數據點,每個區間為一個數據分組
bins = np.linspace (-5, 5, 20)
​
​
## counts為x數值落入區間的計數
counts = np.zeros_like(bins)
​
## 使用searchsorted, 來獲得x每個數據點在bins中落人的區間序號
i = np.searchsorted(bins, x)
print('Searchsorted Index: ',i)
​
​
## 使用at和add, 對x元素在每個區間的元素個數進行計算
np.add.at(counts, i, 1)
​
## 視覺化
plt.plot(bins, counts, ds = 'steps')

執行結果


CC BY-NC-ND 2.0 版权声明

喜欢我的文章吗?
别忘了给点支持与赞赏,让我知道创作的路上有你陪伴。

加载中…

发布评论