【Python】numpy数组常用数据处理(测试代码+api例程)
目录
- 一、数列生成
- 1.按照间隔生成数列(np.array[])
- 2.按照数列数字个数生成数列(np.linspace)
- 二、数列增删改查
- 1.1 数组末尾添加数据(np.append)
- 1.2 数组指定索引位置添加数据(np.insert)
- 2.数列删除元素(np.delete)
- 3. 数列修改元素(通过索引和切片得到的变量直接赋值修改 )
- **4. 数列查询元素**
- **4.1 基础索引与切片**
- **4.2 条件查询(布尔索引)**
- **4.3 位置索引查询**
- **4.4 高级索引技巧**
- **4.5 嵌套结构与对象查询
- **4.6 性能优化建议**
- **完整代码示例**
- **关键总结**
- 数据清洗 NumPy数组操作与数据清洗指南:数据去重详解
- 一、数据去重函数:numpy.unique()
- 函数原型与参数说明
- 基本用法示例
- 高级参数应用
- 1. 获取元素首次出现位置(`return_index`)
- 2. 重构原始数组(`return_inverse`)
- 3. 统计元素出现次数(`return_counts`)
- 多维数组按轴去重
- 二、其他去重方法对比
- 1. 集合(Set)去重
- 2. 有序字典(OrderedDict)去重
- 3. Pandas去重
- 三、性能对比与选择建议
- 四、实用技巧与注意事项
- 五、综合应用示例
- 总结
欢迎关注 『Python』 系列,持续更新中
欢迎关注 『Python』 系列,持续更新中
一、数列生成
1.按照间隔生成数列(np.array[])
(行内for循环快速生成),注意区间左闭右开 range(开始,结束,间隔)
print("1.按照间隔生成数列(行内for循环快速生成),注意区间左闭右开 range(开始,结束,间隔)")
a=np.array([x for x in range(1,11)])
print(a)
2.按照数列数字个数生成数列(np.linspace)
注意区间左闭右闭 numpy.linspace(开始,结束,个数(默认50))
print("2.按照数列数字个数生成数列,注意区间左闭右闭 numpy.linspace(开始,结束,个数(默认50))")
b=np.linspace(1,50)
print(b)
b2=np.linspace(0,10,2)#总个数为11
print(b2)
二、数列增删改查
1.1 数组末尾添加数据(np.append)
numpy.append(arr, values, axis=None)
- arr:输入数组
- values:要向arr添加的值,需要和arr形状相同(除了要添加的轴)
- axis:默认为 None。当axis无定义时,是横向加成,返回总是为一维数组!当axis有定义的时候,分别为0和1的时候。当axis有定义的时候,分别为0和1的时候(列数要相同)。当axis为1时,数组是加在右边(行数要相同)。
- 注意,与列表的append不同,需要用a= 来接收返回的新增元素的np数组。在数组的末尾添加值,append 函数返回的始终是一个一维数组
- 单维度
print("1.数列增加元素append")
a=np.array([])#一个空数列
print(a)#[]
a=np.append(a,1)#注意,与列表的append不同,需要用a= 来接收返回的新增元素的np数组
# 在数组的末尾添加值,append 函数返回的始终是一个一维数组
print(a)#[1.]
- 多维度示例
import numpy as np
a = np.array([[1, 2, 3], [4, 5, 6]])
print(a)
print(np.append(a, [[11, 12, 13]], axis=0))
#沿轴 0 添加元素:
#[[1 2 3]
# [4 5 6]
# [11 12 13]]
1.2 数组指定索引位置添加数据(np.insert)
numpy.insert(ary, indices_or_sections, axis)
- ary:被分割的数组
- indices_or_sections:如果是一个整数,就用该数平均切分,如果是一个数组,为沿轴切分的位置(左开右闭)
- axis:设置沿着哪个方向进行切分,默认为 0,横向切分,即水平方向。为 1 时,纵向切分,即竖直方向。
- 函数在给定索引之前,沿给定轴在输入数组中插入值。如果值的类型转换为要插入,则它与输入数组不同。 插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开为一维数组。
a = np.array([[1, 2], [3, 4], [5, 6]])
print(a)
print(np.insert(a, 1, 123))
print(np.insert(a, 1, 123, axis=0))
print(np.insert(a, 1, 123, axis=1))
# np.insert(a, 1, 123): array([ 1, 123, 2, 3, 4, 5, 6])
# np.insert(a, 1, 123, axis=0): array([[ 1, 2],
# [123, 123],
# [ 3, 4],
# [ 5, 6]])
# np.insert(a, 1, 123, axis=1): array([[ 1, 123, 2],
# [ 3, 123, 4],
# [ 5, 123, 6]])
2.数列删除元素(np.delete)
numpy.delete(arr, obj, axis)
- arr:输入数组
- obj:可以被切片,整数或者整数数组,表明要从输入数组删除的子数组
- axis:沿着它删除给定子数组的轴,如果未提供,则输入数组会被展开
- 基础示例
print("2.数列删除元素")
b=np.array([x for x in range(0,11)])
print(b)
b=np.delete(b,2)#删除了从0开始索引为2的元素
print(b)
- 更多示例
a = np.arange(12).reshape(3, 4)
print(a)
print(np.delete(a, 5)) #未传递axis参数,再插入之前数组会被展开
print(np.delete(a, 1, axis=0)) #删除第二行
b = np.arange(1, 11)
print(b)
print(b[np.s_[::2]]) #np.s_可以当作索引
print(np.delete(b, np.s_[::2])) #删去索引为2的倍数的元素
# a: array([[ 0, 1, 2, 3],
# [ 4, 5, 6, 7],
# [ 8, 9, 10, 11]])
# np.delete(a, 5): array([ 0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11])
# np.delete(a, 1, axis=0): array([[ 0, 1, 2, 3],
# [ 8, 9, 10, 11]])
# b: array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
# b[np.s_[::2]]: array([1, 3, 5, 7, 9])
# np.delete(b, np.s_[::2]): array([ 2, 4, 6, 8, 10])
3. 数列修改元素(通过索引和切片得到的变量直接赋值修改 )
c=np.array([x for x in range(0,11)])
print(c)
c[2]=100#把索引2位置赋值100
print(c)
4. 数列查询元素
4.1 基础索引与切片
-
一维数组索引
通过整数索引直接访问元素,支持正负索引(负数表示倒数):import numpy as np arr = np.array([10, 20, 30, 40, 50]) print(arr[0]) # 10(首元素) print(arr[-1]) # 50(末元素)[4,5](@ref)
-
多维数组索引
用逗号分隔不同维度的索引值:arr_2d = np.array([[1, 2, 3], [4, 5, 6]]) print(arr_2d[1, 0]) # 4(第1行第0列)[8](@ref)
-
切片操作
语法:[start:end:step]
(左闭右开区间):arr = np.array([0, 1, 2, 3, 4, 5]) print(arr[1:4]) # [1, 2, 3](索引1到3) print(arr[::2]) # [0, 2, 4](步长为2)[4,8](@ref)
4.2 条件查询(布尔索引)
通过逻辑表达式筛选满足条件的元素:
arr = np.array([3, 5, 7, 9, 11])
mask = arr > 5
print(arr[mask]) # [7, 9, 11](所有大于5的元素)[6,8](@ref)
复合条件:
mask = (arr > 4) & (arr < 10) # 且关系
print(arr[mask]) # [5, 7, 9][5](@ref)
4.3 位置索引查询
-
查找单个元素位置
使用index()
方法(仅适用于列表):lst = [10, 20, 30, 20] try:idx = lst.index(20) # 返回第一个匹配项的索引print(idx) # 1 except ValueError:print("元素不存在")[3,5](@ref)
-
查找所有匹配位置
结合enumerate()
和列表推导式:lst = [10, 20, 30, 20] positions = [i for i, x in enumerate(lst) if x == 20] print(positions) # [1, 3][3,5](@ref)
-
NumPy高效定位
使用np.where()
返回满足条件的索引数组:arr = np.array([10, 20, 30, 20]) positions = np.where(arr == 20)[0] print(positions) # [1, 3][3,6](@ref)
4.4 高级索引技巧
-
花式索引(Fancy Indexing)
用整数数组同时访问多个不连续位置:arr = np.array([0, 10, 20, 30, 40]) print(arr[[1, 3, 4]]) # [10, 30, 40][6,7](@ref)
-
多维花式索引
组合行列索引数组:arr_2d = np.array([[1, 2], [3, 4], [5, 6]]) rows = [0, 2] cols = [1, 0] print(arr_2d[rows, cols]) # [2, 5]((0,1)和(2,0)的元素)[7](@ref)
**4.5 嵌套结构与对象查询
-
嵌套列表查询
逐层遍历定位元素:nested_list = [[1, 2], [3, 4], [5, 6]] for i, sublist in enumerate(nested_list):if 4 in sublist:col_idx = sublist.index(4)print(f"位置: ({i}, {col_idx})") # (1, 1)[3](@ref)
-
自定义对象查询
根据对象属性匹配:class Point:def __init__(self, x, y):self.x = xself.y = y points = [Point(1,2), Point(3,4)] idx = next(i for i, p in enumerate(points) if p.x == 3) print(idx) # 1[3](@ref)
4.6 性能优化建议
场景 | 推荐方法 | 原因 |
---|---|---|
小规模列表 | index() 或列表推导式 | 代码简洁,内存开销小 |
大规模数值数组 | np.where() | 向量化操作,速度提升10倍以上 |
频繁查询 | 转换为字典或集合 | 哈希表查询复杂度O(1) |
避免修改原数据 | 使用.copy() | 防止切片视图意外修改原数组 |
完整代码示例
import numpy as np# 基础索引与切片
arr = np.arange(10) # [0,1,2,...,9]
print("切片示例:", arr[3:7]) # [3,4,5,6]# 条件查询
arr = np.array([12, 15, 18, 21])
print("大于15的元素:", arr[arr > 15]) # [18,21]# 位置索引查询
positions = np.where(arr % 2 == 0)[0]
print("偶数索引:", positions) # [0,2]# 花式索引
data = np.array([[10,20], [30,40], [50,60]])
print("花式索引结果:", data[[0,2], [1,0]]) # [20,50]
关键总结
- 基础访问:索引和切片是核心,注意切片是视图(共享内存)。
- 条件筛选:布尔索引是NumPy的向量化优势,避免Python循环。
- 定位优化:小数据用
index()
,大数据用np.where()
。 - 嵌套结构:逐层遍历时优先用
in
判断存在性,避免异常。 - 性能陷阱:
- 避免在循环中重复计算条件(如
arr > 5
应预计算) - 超大数据考虑分块处理(
np.memmap
内存映射)
- 避免在循环中重复计算条件(如
数据清洗 NumPy数组操作与数据清洗指南:数据去重详解
一、数据去重函数:numpy.unique()
numpy.unique()
是NumPy库中专门用于处理数组去重的核心函数,它不仅能移除重复值,还能提供多种附加功能。
函数原型与参数说明
numpy.unique(arr, return_index=False, return_inverse=False, return_counts=False, axis=None)
参数详解:
参数 | 类型 | 说明 |
---|---|---|
arr | 数组 | 输入数组,可以是任意维度的NumPy数组 |
return_index | bool | 为True时返回去重元素在原数组的首次出现索引 |
return_inverse | bool | 为True时返回原数组元素在去重数组中的索引 |
return_counts | bool | 为True时返回去重元素在原数组的出现次数 |
axis | int | 指定操作的维度轴(0=行,1=列,None=展平为一维) |
基本用法示例
import numpy as np# 一维数组去重
arr = np.array([3, 1, 2, 2, 3, 4, 5, 4])
unique_arr = np.unique(arr)
print(unique_arr) # 输出: [1 2 3 4 5]# 二维数组默认展平去重
arr_2d = np.array([[1, 2, 3], [3, 4, 5], [1, 2, 3]])
print(np.unique(arr_2d)) # 输出: [1 2 3 4 5]
高级参数应用
1. 获取元素首次出现位置(return_index
)
values, indices = np.unique(arr, return_index=True)
print("去重值:", values) # [1 2 3 4 5]
print("首次出现位置:", indices) # [1 2 0 5 6]
2. 重构原始数组(return_inverse
)
values, inverse = np.unique(arr, return_inverse=True)
print("去重值:", values) # [1 2 3 4 5]
print("重构索引:", inverse) # [2 0 1 1 2 3 4 3]
reconstructed = values[inverse]
print("重构数组:", reconstructed) # [3 1 2 2 3 4 5 4]
3. 统计元素出现次数(return_counts
)
values, counts = np.unique(arr, return_counts=True)
print("去重值:", values) # [1 2 3 4 5]
print("出现次数:", counts) # [1 2 2 2 1]
多维数组按轴去重
# 创建三维数组
arr = np.array([[[1, 2], [3, 4], [1, 2]],[[5, 6], [1, 2], [5, 6]],[[7, 8], [3, 4], [7, 8]]
])# 沿行去重 (axis=0)
print("行去重:\n", np.unique(arr, axis=0))
# 输出:
# [[[1 2]
# [3 4]
# [1 2]]
#
# [[5 6]
# [1 2]
# [5 6]]
#
# [[7 8]
# [3 4]
# [7 8]]]# 沿列去重 (axis=1)
print("\n列去重:\n", np.unique(arr, axis=1))
# 输出:
# [[[1 2]
# [3 4]]
#
# [[1 2]
# [5 6]]
#
# [[3 4]
# [7 8]]]
二、其他去重方法对比
虽然numpy.unique()
是NumPy中最直接的去重方法,但Python还提供了其他替代方案:
1. 集合(Set)去重
arr = [3, 1, 2, 2, 3, 4, 5, 4]
unique_list = list(set(arr))
print(unique_list) # [1, 2, 3, 4, 5]
特点:简单高效但不保留顺序
2. 有序字典(OrderedDict)去重
from collections import OrderedDict
unique_list = list(OrderedDict.fromkeys(arr))
print(unique_list) # [3, 1, 2, 4, 5]
特点:保持原始顺序但需要额外导入模块
3. Pandas去重
import pandas as pd
df = pd.DataFrame(arr, columns=['values'])
unique_df = df.drop_duplicates()
print(unique_df['values'].tolist()) # [3, 1, 2, 4, 5]
特点:适合处理DataFrame结构数据
三、性能对比与选择建议
方法 | 优势 | 劣势 | 适用场景 |
---|---|---|---|
numpy.unique() | 支持多维数组 返回丰富统计信息 | 结果自动排序 | 数值数据科学计算 |
集合(set) | 速度最快(O(n)) | 不保留顺序 | 简单快速去重 |
字典(dict) | 保留插入顺序 | 需要额外转换 | 需要保留顺序的简单数据 |
Pandas | 处理DataFrame方便 | 依赖Pandas库 | DataFrame数据处理 |
最佳实践建议:
- 纯数值数组处理优先使用
numpy.unique()
- 需要保留原始顺序时使用字典
dict.fromkeys()
- 处理DataFrame数据时使用Pandas的
drop_duplicates()
- 简单列表去重可使用集合(set)转换
四、实用技巧与注意事项
-
保持原始顺序:使用
return_index
参数arr = np.array([3, 1, 2, 2, 3, 4, 5, 4]) _, idx = np.unique(arr, return_index=True) sorted_idx = np.sort(idx) print(arr[sorted_idx]) # [3 1 2 4 5]
-
处理特殊值:
# 包含NaN值的数组 arr_nan = np.array([3.0, 1.0, np.nan, 2.0, np.nan]) unique_nan = np.unique(arr_nan) print(unique_nan) # [ 1. 2. 3. nan]
-
性能优化:对于超大型数组(>1e6元素),可考虑分块处理:
def chunked_unique(arr, chunk_size=1000000):chunks = [arr[i:i+chunk_size] for i in range(0, len(arr), chunk_size)]unique_vals = np.unique(np.concatenate([np.unique(chunk) for chunk in chunks]))return unique_vals
-
内存优化:使用
return_inverse
重构数组比存储原数组更省内存
五、综合应用示例
# 创建包含重复数据的二维数组
data = np.array([[101, 'John', 'Sales'],[102, 'Anna', 'Engineering'],[101, 'John', 'Sales'],[103, 'Peter', 'Marketing'],[102, 'Anna', 'Engineering']
])# 按员工ID去重并统计出现次数
ids = data[:, 0]
unique_ids, indices, counts = np.unique(ids, return_index=True, return_counts=True)# 创建去重后的数据表
unique_data = data[indices]# 添加出现次数列
result = np.column_stack((unique_data, counts.astype(str)))print("去重结果:")
print(result)
"""
输出:
[['101' 'John' 'Sales' '2']['102' 'Anna' 'Engineering' '2']['103' 'Peter' 'Marketing' '1']]
"""
通过掌握numpy.unique()
及其相关方法,能高效处理各种数据去重需求,为后续数据分析提供干净、准确的数据基础。
总结
大家喜欢的话,给个👍,点个关注!继续跟大家分享敲代码过程中遇到的问题!
版权声明:
发现你走远了@mzh原创作品,转载必须标注原文链接
Copyright 2022 mzh
Crated:2022-1-10
欢迎关注 『Python』 系列,持续更新中
欢迎关注 『Python』 系列,持续更新中
【Python安装第三方库一行命令永久提高速度】
【使用PyInstaller打包Python文件】
【更多内容敬请期待】