numpy之searchsorted使用方法

本文介绍了np.searchsorted函数,该函数用于在数组a中插入数组v(不执行插入)并返回插入位置下标列表。阐述了其参数含义,包括输入数组a、插入值v、查询方向side和存放a元素index的sorter。还进行了单个元素和列表测试,提及a非升序情况及用该函数替换数组值的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 定义:

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

在数组a中插入数组v(并不执行插入操作),返回一个下标列表,这个列表指明了v中对应元素应该插入在a中那个位置上

 

2. 参数


a : 1-D array_like

输入数组。当sorter参数为None的时候,a必须为升序数组;否则,sorter不能为空,存放a中元素的index,用于反映a数组的升序排列方式。

v : array_like
插入a数组的值,可以为单个元素,list或者array。

side : {'left', 'right'}, optional

查询方向:

当为left时,将返回第一个符合条件的元素下标;

当为right时,将返回最后一个符合条件的元素下标,如果没有符合的元素,将返回0或者N(a的长度)

sorter : 1-D array_like, optional

存放a数组元素的index,index对应元素为升序。

摘抄与博客:https://blog.youkuaiyun.com/qq_17753903/article/details/85165637


 

3. 单个元素测试

import numpy as np
 
a = np.array([0,1,5,9,11,18,26,33])
print(a)

result1 = np.searchsorted(a, 15)                      # result1 = 5, 默认side为left
print('result1:', result1)
result2 = np.searchsorted(a, 15, side='left')         # result2 = 5
print('result2:', result2)
result3 = np.searchsorted(a, 15, side='right')        # result3 = 5
print('result3:', result3)

result4 = np.searchsorted(a, -1, side='left')         # result4 = 0
print('result4:', result4)
result5 = np.searchsorted(a, -1, side='right')        # result5 = 0
print('result5:', result5)

result6 = np.searchsorted(a, 35, side='left')         # result6 = 8
print('result6:', result6)
result7 = np.searchsorted(a, 35, side='right')        # result7 = 8
print('result7:', result7)
## 这组实验说明:
## 1)searchsorted side的默认模式为left
## 2)当搜索一个元组a中不存在的元素时,side模式不管用,如果这个元素比a的最小值还小,就返回0,如果比a的最大值还大,就返回数组a的长度N
## 3)如果这个不存在的元素位于数组a的中间时,返回比它大的那个元素的位置


result8 = np.searchsorted(a, 11, side='left')         # result8 = 4
print('result8:', result8)
result9 = np.searchsorted(a, 11, side='right')        # result9 = 5
print('result9:', result9)

result10 = np.searchsorted(a, 0, side='left')         # result10 = 0
print('result10:', result10)
result11 = np.searchsorted(a, 0, side='right')        # result11 = 1
print('result11:', result11)

result12 = np.searchsorted(a, 33, side='left')        # result12 = 7
print('result12:', result12)
result13 = np.searchsorted(a, 33, side='right')       # result13 = 8
print('result13:', result13)
## 这组实验说明:
## 1)如果搜索的元素存在于数组a中,left方式和right方式的返回值是不同的
## 2)对于left,返回的是与这个元素相等的元素的位置
## 3)对于right,返回的是与这个元素相等的元素的下一个位置

 

4. 列表测试

列表测试的结果与单个元素的测试一样,只是返回的也是一个列表

result14 = np.searchsorted(a, [-1, 0, 11, 15, 33, 35], side='left')
print('result14:', result14)      # result14 = [0 0 4 5 7 8]
result15 = np.searchsorted(a, [-1, 0, 11, 15, 33, 35], side='right')
print('result15:', result15)      # result15 = [0 1 5 5 8 8]

 

5. a不是升序的情况

np.random.shuffle(a)
print('a =', a)                   # a = [ 0  5 26 33 11  9 18  1]

a_sort = np.argsort(a)
print('a_sort =', a_sort)         # a_sort = [0 7 1 5 4 6 2 3]
result16 = np.searchsorted(a, [-1, 0, 11, 15, 33, 35], side='left', sorter=a_sort)
print('result16:', result16)      # result16 = [0 0 4 5 7 8]
result17 = np.searchsorted(a, [-1, 0, 11, 15, 33, 35], side='right', sorter=a_sort)
print('result17:', result17)      # result17 = [0 1 5 5 8 8]
## 得到与上面一样的结果

 

6. 利用searchsorted来替换数组里面的值

import numpy as np

img = np.random.randint(0, 10, (10,10))
# 创造一个随机整形数组
print(img)
shape = img.shape
# img = np.ravel(img)
ids_img, sizes_img = np.unique(img, return_counts=True)
# 计算这个随机数组中不同的id,以及他们对应的数量
print('ids_img =', ids_img)
print('sizes_img =', sizes_img)
print('len of ids_img:', len(ids_img))

ids_dict = dict(zip(ids_img, sizes_img))
# 将id和他们的数量定义为字典
print('ids_dict =', ids_dict)

sizes_sort = sorted(ids_dict.items(), key=lambda ids_dict:ids_dict[1], reverse=True)
# 按字典的value值大小就行排序
print(sizes_sort)
sizes_sort = dict(sizes_sort[:5])
# 取出前面数量最大的5个id和数量
print(sizes_sort)

ids_need = list(sizes_sort.keys())
maxval = np.max(img)
to_vals = range(1, len(sizes_sort)+1) + maxval
# 定义这5个id想变化到的新id
print('to_vals =', to_vals)
d = dict(zip(ids_need, to_vals))

d2 = dict()
for i in ids_img:
    if i in d:
        d2[i] = d[i]
    else:
        d2[i] = maxval 
# 创建一个字典,字典的key包含img中的所有id,字典的value,如果id在之前的五个id里面
# value就是他们的value,否则为img的最大值

from_label = d2.keys()
print('from_label =', from_label)
# 所有旧id
to_label = d2.values()
print('to_label =', to_label)
# 所有新id

from_label = np.array(list(from_label))
to_label = np.array(list(to_label))
# 从字典转换为numpy
##########################################################
# 核心步骤:
sort_idx = np.argsort(from_label)
# 读取from_label数组的升序下标
print('sort_idx =', sort_idx)
idx = np.searchsorted(from_label, img, sorter = sort_idx)
# 将img插入到from_label的位置,idx的维度与img一样
print(idx)
out = to_label[sort_idx][idx]
# numpy高级索引,按sort_idx排序to_label,然后按照idx的索引将
# to_label[sort_idx]放到out里面去
##########################################################
out = out - maxval
print('out =', out)

输出:

[[0 9 3 5 4 0 9 0 5 0]
 [5 6 2 1 4 7 9 7 0 4]
 [3 3 1 3 1 4 9 9 8 8]
 [3 4 1 9 0 4 4 2 2 7]
 [8 5 0 0 6 5 2 6 9 1]
 [4 6 7 8 0 2 4 0 7 0]
 [6 6 9 5 9 2 3 2 6 9]
 [7 4 6 1 9 1 4 1 2 9]
 [7 7 5 0 3 5 4 4 1 4]
 [9 3 0 6 4 6 2 6 9 8]]
ids_img = [0 1 2 3 4 5 6 7 8 9]
sizes_img = [13  9  9  8 15  8 11  8  5 14]
len of ids_img: 10
ids_dict = {0: 13, 1: 9, 2: 9, 3: 8, 4: 15, 5: 8, 6: 11, 7: 8, 8: 5, 9: 14}
[(4, 15), (9, 14), (0, 13), (6, 11), (1, 9), (2, 9), (3, 8), (5, 8), (7, 8), (8, 5)]
{4: 15, 9: 14, 0: 13, 6: 11, 1: 9}
to_vals = [10 11 12 13 14]
from_label = dict_keys([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
to_label = dict_values([12, 14, 9, 9, 10, 9, 13, 9, 9, 11])
sort_idx = [0 1 2 3 4 5 6 7 8 9]
[[0 9 3 5 4 0 9 0 5 0]
 [5 6 2 1 4 7 9 7 0 4]
 [3 3 1 3 1 4 9 9 8 8]
 [3 4 1 9 0 4 4 2 2 7]
 [8 5 0 0 6 5 2 6 9 1]
 [4 6 7 8 0 2 4 0 7 0]
 [6 6 9 5 9 2 3 2 6 9]
 [7 4 6 1 9 1 4 1 2 9]
 [7 7 5 0 3 5 4 4 1 4]
 [9 3 0 6 4 6 2 6 9 8]]
out = [[3 2 0 0 1 3 2 3 0 3]
 [0 4 0 5 1 0 2 0 3 1]
 [0 0 5 0 5 1 2 2 0 0]
 [0 1 5 2 3 1 1 0 0 0]
 [0 0 3 3 4 0 0 4 2 5]
 [1 4 0 0 3 0 1 3 0 3]
 [4 4 2 0 2 0 0 0 4 2]
 [0 1 4 5 2 5 1 5 0 2]
 [0 0 0 3 0 0 1 1 5 1]
 [2 0 3 4 1 4 0 4 2 0]]

参考博客:https://blog.youkuaiyun.com/qq_17753903/article/details/85165637

https://blog.youkuaiyun.com/norsd/article/details/76602101

 

<think>嗯,用户之前已经问过关于ndarray的属性,现在又想知道ndarray的方法。这说明他们可能在使用NumPy进行数据处理,需要更深入的理解来操作数组。用户可能是一个刚开始学习NumPy的学生,或者是一个需要处理数据的科研人员,或者是从事数据分析工作的工程师。他们的需求不仅仅是了解属性,还要掌握如何操作数组,所以需要详细的方法介绍。 接下来,我需要确定用户提到的“方法”具体指哪些。因为NumPy的ndarray有很多方法,可能需要分类别来介绍,比如数学运算、形状操作、统计方法、元素操作、排序和查找、集合操作、文件操作等。这样结构清晰,用户查找起来也方便。 考虑到用户之前得到的是属性的详细说明,这次方法的介绍也应该保持同样的详细程度,每个方法最好有示例代码和适用场景。同时,要注意区分方法和函数的区别,比如np.sort()是函数,而arr.sort()是方法,这点需要说明清楚,避免用户混淆。 另外,用户可能对何时使用方法而不是函数存在疑问,比如为什么有些操作既有函数形式又有方法形式。这时候需要给出指导,例如在链式调用时使用方法更简洁,或者根据代码的可读性来选择。 还要注意一些方法的原地操作特性,比如resize()和reshape()的区别,sort()和argsort()的不同用途。这些细节对于正确使用NumPy非常重要,避免用户在使用时出现错误。 最后,可能需要总结一下常用的方法及其应用场景,帮助用户快速查阅。同时提醒用户注意方法的副作用,比如原地操作会改变原数组,而某些方法返回的是视图而非副本,影响内存使用。 需要检查是否有遗漏的重要方法,比如isnan()、all()、any()这些常用的方法,以及文件操作如tofile()。确保覆盖到用户可能需要的各个方面,同时避免信息过载,保持结构清晰。</think>以下是NumPy中`ndarray`对象的**核心方法**分类详解,配合代码示例说明具体应用场景: --- ### 一、数学运算方法 1. **`sum()`** - 求和 ```python arr = np.array([[1,2], [3,4]]) print(arr.sum()) # 15 (全部元素和) print(arr.sum(axis=0)) # [4 6] (列求和) ``` 2. **`mean()`** - 平均值 ```python print(np.array([1,2,3,4]).mean()) # 2.5 ``` 3. **`std()` / `var()`** - 标准差/方差 ```python print(np.array([1,2,3]).std()) # 0.81649658 ``` --- ### 二、形状操作方法 4. **`reshape()`** - 重构形状 ```python arr = np.arange(6) print(arr.reshape(2,3)) # [[0 1 2] [3 4 5]] ``` 5. **`flatten()` / `ravel()`** - 扁平化 ```python print(arr.reshape(2,3).flatten()) # 返回拷贝 [0 1 2 3 4 5] print(arr.ravel()) # 返回视图 [0 1 2 3 4 5] ``` 6. **`resize()`** - 原地调整尺寸 ```python arr.resize(3,2) # 直接修改原数组形状 ``` --- ### 三、统计分析方法 7. **`max()` / `min()`** - 极值 ```python arr = np.random.rand(3,4) print(arr.max(axis=1)) # 每行的最大值 ``` 8. **`argmax()` / `argmin()`** - 极值索引 ```python print(np.array([3,1,2]).argmax()) # 0 (最大值的索引) ``` 9. **`cumsum()` / `cumprod()`** - 累积计算 ```python print(np.array([1,2,3]).cumsum()) # [1 3 6] ``` --- ### 四、元素操作方法 10. **`astype()`** - 类型转换 ```python arr = np.array([1.5, 2.7]) print(arr.astype(np.int32)) # [1 2] ``` 11. **`round()`** - 四舍五入 ```python print(np.array([1.234, 5.678]).round(2)) # [1.23 5.68] ``` 12. **`clip()`** - 数值裁剪 ```python print(np.array([1,5,10]).clip(2,8)) # [2 5 8] ``` --- ### 五、排序与查找 13. **`sort()`** - 原地排序 ```python arr = np.array([3,1,2]) arr.sort() # 直接修改原数组 → [1 2 3] ``` 14. **`argsort()`** - 排序索引 ```python print(np.array([3,1,2]).argsort()) # [1 2 0] ``` 15. **`searchsorted()`** - 有序插入 ```python print(np.array([1,3,5]).searchsorted(4)) # 2 (插入位置索引) ``` --- ### 六、集合操作 16. **`unique()`** - 唯一值 ```python print(np.array([2,1,2,3,3]).unique()) # [1 2 3] ``` 17. **`in1d()`** - 成员检测 ```python print(np.in1d([0,1,2], [1,3])) # [False True False] ``` --- ### 七、文件操作 18. **`tofile()`** - 二进制存储 ```python arr = np.arange(5) arr.tofile('data.bin') ``` 19. **`dump()` / `dumps()`** - 序列化 ```python with open('data.pkl', 'wb') as f: arr.dump(f) # 序列化保存 ``` --- ### 八、特殊方法 20. **`fill()`** - 填充标量 ```python arr = np.empty(3) arr.fill(5) # [5. 5. 5.] ``` 21. **`nonzero()`** - 非零索引 ```python print(np.array([0,2,0,4]).nonzero()) # (array([1,3]),) ``` 22. **`repeat()`** - 元素重复 ```python print(np.array([1,2]).repeat(2)) # [1 1 2 2] ``` --- ### 方法 vs 函数 选择指南 | 场景 | 推荐方式 | 示例 | |-------|---------|------| | 链式操作 | 方法调用 | `arr.reshape(2,3).sum(axis=1)` | | 保持原数组 | 函数调用 | `np.sort(arr)` (返回新数组) | | 就地修改 | 方法调用 | `arr.sort()` (直接修改原数组) | --- ### 关键方法总结表 | 类别 | 高频方法 | 典型应用场景 | |------|----------|-------------| | 数学计算 | `sum()`, `mean()` | 数据聚合分析 | | 形状操作 | `reshape()`, `T` | 图像通道转换 | | 数据清洗 | `clip()`, `astype()` | 异常值处理 | | 排序筛选 | `sort()`, `argsort()` | 特征排序 | | 内存优化 | `copy()`, `view()` | 大数据处理 | **重要特性说明**: 1. 所有数学方法均支持`axis`参数控制计算维度 2. `reshape()`方法要求总元素数不变,`resize()`允许填充/截断 3. 带`out`参数的方法(如`np.add(a,b,out=c)`)可避免内存重复分配
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深山里的小白羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值