You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:700万条数据集绘制Histogram的Python性能优化方案

700万条数据频率统计与直方图绘制的性能优化方案

瓶颈分析

你当前代码运行缓慢的核心原因:

  • 纯Python循环逐行读取并构建列表,处理700万条数据的开销极大
  • 对字符串类型数据执行np.unique或手动字典统计,效率远低于数值型数组的向量化操作
  • 若唯一值数量过多,plt.bar绘制大量柱子会占用巨量计算资源

优化方案

1. 优先转为数值类型(关键提速点)

如果你的数据是整数/浮点数,绝对不要以字符串形式处理,直接读取为numpy数值数组,这能让速度提升几个数量级。

2. 高效读取文件

用numpy的loadtxt直接读取文件为数值数组,彻底避免纯Python循环:

import numpy as np
import matplotlib.pyplot as plt

file_path = "D:/results/planarity2.txt"
# 整数用dtype=int,浮点数用dtype=np.float64
data = np.loadtxt(file_path, dtype=np.float64)

3. 快速统计频率

方案A:numpy向量化操作(最快)

  • 整数类型数据用np.bincount:
counts = np.bincount(data.astype(int))
unique_values = np.arange(len(counts))
# 过滤掉计数为0的项(可选)
mask = counts > 0
unique_values = unique_values[mask]
counts = counts[mask]
  • 浮点数/非整数离散值用np.unique直接处理数值数组:
unique_values, counts = np.unique(data, return_counts=True)

方案B:collections.Counter(字符串数据首选)

如果必须处理字符串类型数据,用Counter代替手动字典统计,内部实现比纯Python循环高效得多:

from collections import Counter

with open(file_path, "r") as f:
    # 生成器直接传入,避免先构建大列表
    value_frequency = Counter(line.strip() for line in f)
unique_values = list(value_frequency.keys())
counts = list(value_frequency.values())

4. 优化绘图逻辑

如果唯一值数量极大(比如超过1000),plt.bar会因渲染过多柱子变得极慢,此时改用plt.hist自动分箱渲染:

plt.hist(data, bins='auto', edgecolor='black', alpha=0.7)
plt.xlabel('数值')
plt.ylabel('频率')
plt.title('数值频率分布直方图')
plt.show()

若必须绘制精确离散值:

  • 只保留频率Top N的取值(比如前200个)
  • 关闭edgecolor减少渲染开销
  • 对字符串标签添加旋转避免重叠:plt.xticks(rotation=45, ha='right')

完整优化代码示例

数值型数据版本

import numpy as np
import matplotlib.pyplot as plt

file_path = "D:/results/planarity2.txt"

# 快速读取数值数据
data = np.loadtxt(file_path, dtype=np.float64)

# 快速统计频率
unique_values, counts = np.unique(data, return_counts=True)

# 根据唯一值数量选择绘图方式
if len(unique_values) < 1000:
    plt.bar(unique_values, counts, edgecolor='black', alpha=0.7)
else:
    plt.hist(data, bins='auto', edgecolor='black', alpha=0.7)

plt.xlabel('数值')
plt.ylabel('频率')
plt.title('数值频率分布直方图')
plt.show()

字符串型数据版本

from collections import Counter
import matplotlib.pyplot as plt

file_path = "D:/results/planarity2.txt"

# 快速统计频率
with open(file_path, "r") as f:
    value_frequency = Counter(line.strip() for line in f)

# 只保留前200个高频值(避免绘图卡顿)
sorted_items = sorted(value_frequency.items(), key=lambda x: x[1], reverse=True)[:200]
unique_values, counts = zip(*sorted_items)

plt.bar(unique_values, counts, edgecolor='black', alpha=0.7)
plt.xlabel('取值')
plt.ylabel('频率')
plt.title('取值频率分布直方图')
plt.xticks(rotation=45, ha='right')
plt.show()

内容的提问来源于stack exchange,提问作者youssef

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 18:53:11