Python如何快速查找NumPy数组重复行_利用unique的axis参数实现

来源:站长站作者:长沙SEO公司头衔:草根站长
导读:本期聚焦于小伙伴创作的《Python如何快速查找NumPy数组重复行_利用unique的axis参数实现》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Python如何快速查找NumPy数组重复行_利用unique的axis参数实现》有用,将其分享出去将是对创作者最好的鼓励。

在Python的数值计算场景中,NumPy二维数组的重复行查找是常见需求,比如数据清洗时需要去除重复的样本记录,或者统计重复行的出现频率。NumPy内置的unique函数配合axis参数,能够以向量化的方式快速完成这个任务,避免低效的循环遍历。

Python如何快速查找NumPy数组重复行_利用unique的axis参数实现

unique函数axis参数基础用法

NumPy的np.unique函数默认会将数组展平后去重,当指定axis=0时,会按照行维度进行去重,返回去重后的唯一行数组。同时该函数还支持返回多个可选输出,帮助我们定位重复行的相关信息。

函数的基本语法如下:

import numpy as np

# 创建包含重复行的二维数组
arr = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [1, 2, 3],
    [7, 8, 9],
    [4, 5, 6]
])

# 使用axis=0参数去重,返回唯一行
unique_rows = np.unique(arr, axis=0)
print("去重后的唯一行:")
print(unique_rows)

上述代码的输出结果为:

去重后的唯一行:
[[1 2 3]
 [4 5 6]
 [7 8 9]]

获取重复行的索引和出现次数

除了返回去重后的行,np.unique还可以通过设置返回参数,得到每个唯一行在原数组中的首次出现索引、所有出现索引以及出现次数,这些信息可以帮助我们进一步分析重复行的情况。

相关的参数说明:

  • return_index:设为True时,返回每个唯一行在原数组中首次出现的索引
  • return_inverse:设为True时,返回原数组中每个行对应的唯一行索引,可用于还原原数组
  • return_counts:设为True时,返回每个唯一行的出现次数

下面的示例演示如何获取重复行的相关信息:

import numpy as np

arr = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [1, 2, 3],
    [7, 8, 9],
    [4, 5, 6]
])

# 获取唯一行、首次出现索引、逆映射索引、出现次数
unique_rows, first_indices, inverse_indices, counts = np.unique(
    arr, axis=0, return_index=True, return_inverse=True, return_counts=True
)

print("唯一行:")
print(unique_rows)
print("每个唯一行首次出现的索引:", first_indices)
print("原数组每个行对应的唯一行索引:", inverse_indices)
print("每个唯一行的出现次数:", counts)

# 筛选出现次数大于1的重复行
duplicate_rows = unique_rows[counts > 1]
print("重复的行:")
print(duplicate_rows)

上述代码的输出结果为:

唯一行:
[[1 2 3]
 [4 5 6]
 [7 8 9]]
每个唯一行首次出现的索引: [0 1 3]
原数组每个行对应的唯一行索引: [0 1 0 2 1]
每个唯一行的出现次数: [2 2 1]
重复的行:
[[1 2 3]
 [4 5 6]]

自定义函数封装重复行查找逻辑

我们可以将上述逻辑封装成一个通用的函数,方便在不同场景中直接调用,快速获取数组中的重复行以及对应的重复次数。

import numpy as np

def find_duplicate_rows(arr):
    """
    查找NumPy二维数组中的重复行
    :param arr: 输入的二维NumPy数组
    :return: 重复行数组、每个重复行的出现次数
    """
    # 按照行维度去重,返回唯一行和出现次数
    unique_rows, counts = np.unique(arr, axis=0, return_counts=True)
    # 筛选出现次数大于1的行
    duplicate_mask = counts > 1
    duplicate_rows = unique_rows[duplicate_mask]
    duplicate_counts = counts[duplicate_mask]
    return duplicate_rows, duplicate_counts

# 测试封装的函数
test_arr = np.array([
    [10, 20],
    [30, 40],
    [10, 20],
    [50, 60],
    [30, 40],
    [30, 40]
])

dup_rows, dup_counts = find_duplicate_rows(test_arr)
print("测试数组的重复行:")
print(dup_rows)
print("对应重复次数:", dup_counts)

运行上述代码,输出结果如下:

测试数组的重复行:
[[10 20]
 [30 40]]
对应重复次数: [2 3]

性能对比:unique axis参数 vs 循环遍历

对于大规模数组,使用np.unique的axis参数比手动循环遍历的效率高很多,因为NumPy的底层是C实现,向量化操作避免了Python层面的循环开销。下面的示例对比两种方式的性能差异:

import numpy as np
import time

# 生成包含1万行、5列的随机数组,人为添加部分重复行
np.random.seed(42)
base_arr = np.random.randint(0, 100, size=(5000, 5))
test_arr = np.vstack([base_arr, base_arr[:5000]])

# 方法1:使用np.unique axis参数
start = time.time()
unique_rows = np.unique(test_arr, axis=0)
end = time.time()
print("np.unique方法耗时:", end - start, "秒")

# 方法2:循环遍历去重
start = time.time()
seen = []
duplicate_rows_loop = []
for row in test_arr:
    row_tuple = tuple(row)
    if row_tuple in seen:
        if row_tuple not in duplicate_rows_loop:
            duplicate_rows_loop.append(row_tuple)
    else:
        seen.append(row_tuple)
end = time.time()
print("循环遍历方法耗时:", end - start, "秒")

在普通配置的电脑上运行,通常np.unique方法耗时在零点零几秒,而循环遍历方法可能需要数秒甚至更久,数据量越大差距越明显。

注意事项

使用np.unique的axis参数时需要注意几个问题:

  • 输入的数组必须是二维及以上,否则指定axis=0会报错
  • 数组的数据类型需要一致,否则可能会触发类型转换,影响结果正确性
  • 如果数组中包含NaN值,因为NaN不等于NaN,所以包含NaN的行不会被判定为重复行,需要提前处理NaN值

如果数组中存在NaN值,可以先使用np.isnan检测并替换,再进行重复行查找:

import numpy as np

arr_with_nan = np.array([
    [1.0, 2.0],
    [np.nan, 3.0],
    [1.0, 2.0],
    [np.nan, 3.0]
])

# 替换NaN为自定义值,这里用-999代替
arr_filled = np.where(np.isnan(arr_with_nan), -999, arr_with_nan)
unique_rows = np.unique(arr_filled, axis=0)
print("处理NaN后的去重行:")
print(unique_rows)

NumPyunique_axis数组重复行Python数据处理修改时间:2026-07-02 20:45:26

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。