ubnt解决方案
查看: 221|回复: 1

python写法的快速去重

[复制链接]

14

回帖

103

积分

8 小时

在线时间

上等兵

注册时间
2017-8-7
金币
62 个
威望
3 个
荣誉
1 个
累计签到:3 天
连续签到:0 天
[LV.20]漫游旅程
发表于 2024-6-25 19:13 |显示全部楼层
本帖最后由 2521667577 于 2024-6-25 19:40 编辑
代码旨在大型文本快速去重  相比传统的命令行有以下优点
  • 分块处理
    • 使用 read_large_file_in_chunks 函数从输入文件中分块读取数据,每块默认包含 100,000 行
  • 去重处理
    • 在 process_chunk 函数中,对每个数据块进行去重,并将结果后写入临时文件
  • 归并排序临时文件
    • merge_sorted_files 函数负责将所有临时文件中的数据进行归并排序
  • 显示处理进度和剩余时间
    • 使用 tqdm 库在处理过程中显示进度条,根据已处理的行数和总行数估算剩余处理时间。
  • 异常处理
    • 使用 latin-1 编码并忽略解码错误,确保程序在处理非 UTF-8 格式的文本时能够稳定运行
      1. import os
      2. import heapq
      3. import time
      4. from tqdm import tqdm

      5. # 读取大文件,分块处理去重并排序
      6. def read_large_file_in_chunks(file_path, chunk_size=100000):
      7.     with open(file_path, 'r', encoding='latin-1', errors='ignore') as file:
      8.         lines = []
      9.         for line in file:
      10.             lines.append(line.strip())
      11.             if len(lines) >= chunk_size:
      12.                 yield lines
      13.                 lines = []
      14.         if lines:
      15.             yield lines

      16. # 去重并排序后写入临时文件
      17. def process_chunk(lines, temp_dir, chunk_index):
      18.     unique_lines = sorted(set(lines))
      19.     temp_file_path = os.path.join(temp_dir, f'temp_chunk_{chunk_index}.txt')
      20.     with open(temp_file_path, 'w', encoding='utf-8') as temp_file:
      21.         temp_file.write('\n'.join(unique_lines) + '\n')
      22.     return temp_file_path

      23. # 归并排序临时文件并去重
      24. def merge_sorted_files(temp_files, output_file_path, batch_size=100):
      25.     num_files = len(temp_files)
      26.     batched_files = [temp_files[i:i+batch_size] for i in range(0, num_files, batch_size)]
      27.    
      28.     for batch in batched_files:
      29.         open_files = [open(file, 'r', encoding='utf-8') for file in batch]
      30.         pq = []
      31.         
      32.         for file_index, file in enumerate(open_files):
      33.             line = file.readline().strip()
      34.             if line:
      35.                 heapq.heappush(pq, (line, file_index))
      36.         
      37.         with open(output_file_path, 'a', encoding='utf-8') as output_file:
      38.             prev_line = None
      39.             while pq:
      40.                 current_line, file_index = heapq.heappop(pq)
      41.                 if current_line != prev_line:
      42.                     output_file.write(current_line + '\n')
      43.                     prev_line = current_line
      44.                 next_line = open_files[file_index].readline().strip()
      45.                 if next_line:
      46.                     heapq.heappush(pq, (next_line, file_index))
      47.         
      48.         for file in open_files:
      49.             file.close()

      50. def count_lines(file_path):
      51.     with open(file_path, 'r', encoding='latin-1', errors='ignore') as file:
      52.         return sum(1 for line in file)

      53. def remove_duplicates(input_file_path, output_file_path, temp_dir, chunk_size=100000):
      54.     if not os.path.exists(temp_dir):
      55.         os.makedirs(temp_dir)
      56.    
      57.     start_time = time.time()
      58.     total_lines = count_lines(input_file_path)
      59.     chunk_index = 0
      60.     temp_files = []
      61.    
      62.     print("Reading and processing chunks...")
      63.     with tqdm(total=total_lines, desc="Processing chunks") as pbar:
      64.         for chunk in read_large_file_in_chunks(input_file_path, chunk_size):
      65.             temp_file_path = process_chunk(chunk, temp_dir, chunk_index)
      66.             temp_files.append(temp_file_path)
      67.             chunk_index += 1
      68.             pbar.update(len(chunk))
      69.    
      70.     print("Merging sorted chunks...")
      71.     merge_start_time = time.time()
      72.     merge_sorted_files(temp_files, output_file_path)
      73.    
      74.     for temp_file in temp_files:
      75.         os.remove(temp_file)
      76.    
      77.     end_time = time.time()
      78.     print(f"Process completed successfully in {end_time - start_time:.2f} seconds.")
      79.     print(f"Time taken for merging: {end_time - merge_start_time:.2f} seconds.")

      80. # 使用上述函数进行去重
      81. input_file_path = r'D:\zd\small\input.txt'
      82. output_file_path = r'D:\zd\small\output.txt'
      83. temp_dir = r'D:\zd\small\temp'

      84. remove_duplicates(input_file_path, output_file_path, temp_dir)
      复制代码


157

回帖

3570

积分

1387 小时

在线时间

少校

注册时间
2017-4-19
金币
3263 个
威望
1 个
荣誉
0 个

尚未签到

发表于 2024-6-26 14:13 来自手机 |显示全部楼层
本帖最后由 qpalzm123 于 2024-6-26 14:16 编辑

特大字典准确率要验证起来显然费劲,
但是怎么个快法呢
1GB字典完成去重要多少时间?
100GB字典完成去重又要多少时间?
麻烦请给出数据参考一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册 微信登录

本版积分规则

站点统计 | Archiver | 手机版 | 无线门户 ( 粤ICP备11076993号|粤公网安备44010602008359号 ) |网站地图

GMT+8, 2024-6-29 22:58

返回顶部 返回列表