
👋 大家好,欢迎来到我的技术博客! 📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。 🎯 本文将围绕NumPy这个话题展开,希望能为你带来一些启发或实用的参考。 🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获!
文章目录
- Python NumPy – 统计函数:计算数组的平均值与中位数 📊
-
- 什么是平均值和中位数? 🤔
- NumPy中的平均值函数 📈
-
- 基本用法
- 高级参数选项
- 深入理解中位数计算 🎯
-
- 基础中位数计算
- 处理特殊情况
- 实际应用场景 💼
-
- 销售数据分析
- 学生成绩分析
- 性能优化技巧 ⚡
-
- 内存效率的计算
- 批处理大数据
- 错误处理和边界情况 🛡️
-
- 处理空数组
- 数据类型兼容性
- 高级统计分析 🔍
-
- 比较不同统计量
- 时间序列数据的移动平均
- mermaid流程图展示数据处理过程
- 数组维度处理技巧 📐
-
- 三维数组统计
- 条件统计计算
- 自定义统计函数 🛠️
-
- 加权平均值
- 截尾平均值
- 与其他统计库的集成 🔄
-
- 与Pandas集成
- 与SciPy结合进行统计检验
- 实时数据流处理 📡
- 最佳实践总结 📋
-
- 性能优化建议
- 代码质量保证
- 结语与展望 🌟
Python NumPy – 统计函数:计算数组的平均值与中位数 📊
在数据分析和科学计算的世界里,统计函数是不可或缺的工具。NumPy作为Python生态系统中最基础也是最重要的数值计算库之一,提供了丰富的统计函数来帮助我们快速处理和分析数据。今天我们将深入探讨如何使用NumPy来计算数组的平均值和中位数这两个最基本的统计量。
什么是平均值和中位数? 🤔
在开始编码之前,让我们先理解一下这两个重要的统计概念:
平均值(Mean) 是所有数据点的总和除以数据点的数量。它是最常用的集中趋势度量,能够反映数据的整体水平。
中位数(Median) 是将数据集按大小顺序排列后位于中间位置的数值。如果数据个数是偶数,则取中间两个数的平均值。中位数对异常值不敏感,是衡量数据中心位置的稳健指标。
import numpy as np
# 创建一个简单的数组示例
data = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
print(f"原始数据: {data}")
# 计算平均值
mean_value = np.mean(data)
print(f"平均值: {mean_value}")
# 计算中位数
median_value = np.median(data)
print(f"中位数: {median_value}")
NumPy中的平均值函数 📈
NumPy提供了多种计算平均值的方法,最常用的是np.mean()函数。这个函数功能强大且灵活,支持多维数组的各种操作。
基本用法
import numpy as np
# 一维数组
arr_1d = np.array([10, 20, 30, 40, 50])
print(f"一维数组: {arr_1d}")
print(f"平均值: {np.mean(arr_1d)}")
# 二维数组
arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(f"\\n二维数组:\\n{arr_2d}")
print(f"整体平均值: {np.mean(arr_2d)}")
print(f"按行计算平均值: {np.mean(arr_2d, axis=1)}")
print(f"按列计算平均值: {np.mean(arr_2d, axis=0)}")
高级参数选项
np.mean()函数还支持一些高级参数,让我们的计算更加灵活:
# 使用dtype参数指定返回类型
float_arr = np.array([1, 2, 3, 4, 5])
mean_float = np.mean(float_arr, dtype=np.float64)
print(f"指定浮点型结果: {mean_float}")
# 使用out参数将结果存储到预分配的数组中
result_array = np.empty(1)
np.mean(float_arr, out=result_array)
print(f"输出到指定数组: {result_array[0]}")
# 处理包含NaN值的数据
nan_arr = np.array([1, 2, np.nan, 4, 5])
print(f"包含NaN的数组: {nan_arr}")
print(f"普通平均值 (结果为NaN): {np.mean(nan_arr)}")
print(f"忽略NaN的平均值: {np.nanmean(nan_arr)}")
深入理解中位数计算 🎯
中位数是另一个重要的统计量,特别是在存在异常值的情况下,它比平均值更能代表数据的中心趋势。
基础中位数计算
# 一维数组中位数
odd_length = np.array([1, 3, 5, 7, 9])
even_length = np.array([2, 4, 6, 8])
print(f"奇数长度数组: {odd_length}")
print(f"中位数: {np.median(odd_length)}")
print(f"偶数长度数组: {even_length}")
print(f"中位数: {np.median(even_length)}")
# 二维数组中位数
matrix_data = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
print(f"\\n矩阵数据:\\n{matrix_data}")
print(f"整体中位数: {np.median(matrix_data)}")
print(f"按行计算中位数: {np.median(matrix_data, axis=1)}")
print(f"按列计算中位数: {np.median(matrix_data, axis=0)}")
处理特殊情况
# 包含重复值的情况
repeated_values = np.array([1, 1, 2, 2, 2, 3, 3])
print(f"重复值数组: {repeated_values}")
print(f"中位数: {np.median(repeated_values)}")
# 包含负数的情况
negative_values = np.array([–5, –3, –1, 0, 1, 3, 5])
print(f"包含负数的数组: {negative_values}")
print(f"中位数: {np.median(negative_values)}")
# 浮点数精度问题
precision_test = np.array([0.1, 0.2, 0.3])
print(f"浮点数数组: {precision_test}")
print(f"中位数: {np.median(precision_test)}")
实际应用场景 💼
让我们通过一些实际的例子来看看这些统计函数在现实世界中的应用。
销售数据分析
# 模拟一个月的销售数据
daily_sales = np.random.normal(1000, 200, 30) # 平均1000元,标准差200元
daily_sales = np.round(daily_sales, 2)
print("=== 销售数据分析 ===")
print(f"本月销售数据: {daily_sales}")
print(f"日平均销售额: {np.mean(daily_sales):.2f} 元")
print(f"日销售额中位数: {np.median(daily_sales):.2f} 元")
# 找出异常高的销售日
high_sales_days = daily_sales[daily_sales > np.mean(daily_sales) + 2 * np.std(daily_sales)]
print(f"高销售日数据: {high_sales_days}")
print(f"高销售日数量: {len(high_sales_days)}")
学生成绩分析
# 模拟班级学生成绩
class_scores = np.array([85, 92, 78, 96, 88, 73, 91, 87, 94, 82,
89, 95, 76, 84, 90, 83, 93, 79, 86, 97,
100, 75, 81, 98, 77, 80, 99, 74, 72, 71])
print("=== 学生成绩分析 ===")
print(f"班级人数: {len(class_scores)}")
print(f"平均分: {np.mean(class_scores):.2f}")
print(f"中位数分数: {np.median(class_scores):.2f}")
print(f"最高分: {np.max(class_scores)}")
print(f"最低分: {np.min(class_scores)}")
# 成绩分布情况
passing_score = 60
excellent_score = 90
passed_students = np.sum(class_scores >= passing_score)
excellent_students = np.sum(class_scores >= excellent_score)
print(f"及格人数: {passed_students} ({passed_students/len(class_scores)*100:.1f}%)")
print(f"优秀人数: {excellent_students} ({excellent_students/len(class_scores)*100:.1f}%)")
性能优化技巧 ⚡
当处理大量数据时,性能成为一个重要考虑因素。以下是一些优化建议:
内存效率的计算
# 对于大型数组,使用in-place操作可以节省内存
large_array = np.random.rand(1000000)
# 直接计算(可能消耗更多内存)
start_time = time.time()
mean_direct = np.mean(large_array)
time_direct = time.time() – start_time
# 使用更高效的函数
start_time = time.time()
mean_efficient = np.mean(large_array, dtype=np.float32)
time_efficient = time.time() – start_time
print(f"直接计算耗时: {time_direct:.4f}秒")
print(f"高效计算耗时: {time_efficient:.4f}秒")
批处理大数据
def batch_mean(data, batch_size=10000):
"""分批计算大数组的平均值"""
total_sum = 0
total_count = 0
for i in range(0, len(data), batch_size):
batch = data[i:i+batch_size]
total_sum += np.sum(batch)
total_count += len(batch)
return total_sum / total_count
# 测试批处理方法
huge_array = np.random.rand(10000000)
batch_result = batch_mean(huge_array)
direct_result = np.mean(huge_array)
print(f"批处理结果: {batch_result:.6f}")
print(f"直接计算结果: {direct_result:.6f}")
print(f"差异: {abs(batch_result – direct_result):.10f}")
错误处理和边界情况 🛡️
在实际应用中,我们需要考虑各种可能出现的问题:
处理空数组
# 空数组的情况
empty_array = np.array([])
try:
mean_empty = np.mean(empty_array)
print(f"空数组的平均值: {mean_empty}") # 返回NaN
except Exception as e:
print(f"错误: {e}")
try:
median_empty = np.median(empty_array)
print(f"空数组的中位数: {median_empty}") # 返回NaN
except Exception as e:
print(f"错误: {e}")
数据类型兼容性
# 不同数据类型的处理
int_array = np.array([1, 2, 3, 4, 5])
float_array = np.array([1.5, 2.5, 3.5, 4.5, 5.5])
complex_array = np.array([1+2j, 2+3j, 3+4j])
print(f"整数数组平均值: {np.mean(int_array)}")
print(f"浮点数组平均值: {np.mean(float_array)}")
print(f"复数数组平均值: {np.mean(complex_array)}")
# 注意:复数没有自然的排序,因此中位数计算会报错
try:
complex_median = np.median(complex_array)
print(f"复数数组中位数: {complex_median}")
except Exception as e:
print(f"复数中位数计算错误: {e}")
高级统计分析 🔍
除了基本的平均值和中位数,我们还可以进行更深入的统计分析:
比较不同统计量
# 创建一个有偏分布的数据集
skewed_data = np.concatenate([
np.random.normal(50, 5, 90), # 主要集中在50附近
np.random.normal(90, 2, 10) # 少数异常值在90附近
])
print("=== 分布特征分析 ===")
print(f"数据点数量: {len(skewed_data)}")
print(f"平均值: {np.mean(skewed_data):.2f}")
print(f"中位数: {np.median(skewed_data):.2f}")
print(f"众数近似: {np.bincount(np.round(skewed_data).astype(int)).argmax()}")
# 当平均值远大于中位数时,说明分布右偏
if np.mean(skewed_data) > np.median(skewed_data):
print("📊 数据分布呈现右偏特征")
else:
print("📊 数据分布相对对称")
时间序列数据的移动平均
# 模拟股票价格时间序列
days = 100
prices = 100 + np.cumsum(np.random.randn(days) * 0.5)
def moving_average(data, window_size):
"""计算移动平均"""
return np.convolve(data, np.ones(window_size)/window_size, mode='valid')
# 计算不同窗口的移动平均
ma_5 = moving_average(prices, 5)
ma_20 = moving_average(prices, 20)
print("=== 移动平均分析 ===")
print(f"原始价格数据长度: {len(prices)}")
print(f"5日移动平均长度: {len(ma_5)}")
print(f"20日移动平均长度: {len(ma_20)}")
print(f"最新价格: {prices[–1]:.2f}")
print(f"最新5日均线: {ma_5[–1]:.2f}")
print(f"最新20日均线: {ma_20[–1]:.2f}")
mermaid流程图展示数据处理过程
#mermaid-svg-cY66LlL4uEWC5SoN{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-cY66LlL4uEWC5SoN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-cY66LlL4uEWC5SoN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-cY66LlL4uEWC5SoN .error-icon{fill:#552222;}#mermaid-svg-cY66LlL4uEWC5SoN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-cY66LlL4uEWC5SoN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-cY66LlL4uEWC5SoN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-cY66LlL4uEWC5SoN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-cY66LlL4uEWC5SoN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-cY66LlL4uEWC5SoN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-cY66LlL4uEWC5SoN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-cY66LlL4uEWC5SoN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-cY66LlL4uEWC5SoN .marker.cross{stroke:#333333;}#mermaid-svg-cY66LlL4uEWC5SoN svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-cY66LlL4uEWC5SoN p{margin:0;}#mermaid-svg-cY66LlL4uEWC5SoN .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-cY66LlL4uEWC5SoN .cluster-label text{fill:#333;}#mermaid-svg-cY66LlL4uEWC5SoN .cluster-label span{color:#333;}#mermaid-svg-cY66LlL4uEWC5SoN .cluster-label span p{background-color:transparent;}#mermaid-svg-cY66LlL4uEWC5SoN .label text,#mermaid-svg-cY66LlL4uEWC5SoN span{fill:#333;color:#333;}#mermaid-svg-cY66LlL4uEWC5SoN .node rect,#mermaid-svg-cY66LlL4uEWC5SoN .node circle,#mermaid-svg-cY66LlL4uEWC5SoN .node ellipse,#mermaid-svg-cY66LlL4uEWC5SoN .node polygon,#mermaid-svg-cY66LlL4uEWC5SoN .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-cY66LlL4uEWC5SoN .rough-node .label text,#mermaid-svg-cY66LlL4uEWC5SoN .node .label text,#mermaid-svg-cY66LlL4uEWC5SoN .image-shape .label,#mermaid-svg-cY66LlL4uEWC5SoN .icon-shape .label{text-anchor:middle;}#mermaid-svg-cY66LlL4uEWC5SoN .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-cY66LlL4uEWC5SoN .rough-node .label,#mermaid-svg-cY66LlL4uEWC5SoN .node .label,#mermaid-svg-cY66LlL4uEWC5SoN .image-shape .label,#mermaid-svg-cY66LlL4uEWC5SoN .icon-shape .label{text-align:center;}#mermaid-svg-cY66LlL4uEWC5SoN .node.clickable{cursor:pointer;}#mermaid-svg-cY66LlL4uEWC5SoN .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-cY66LlL4uEWC5SoN .arrowheadPath{fill:#333333;}#mermaid-svg-cY66LlL4uEWC5SoN .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-cY66LlL4uEWC5SoN .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-cY66LlL4uEWC5SoN .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cY66LlL4uEWC5SoN .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-cY66LlL4uEWC5SoN .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cY66LlL4uEWC5SoN .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-cY66LlL4uEWC5SoN .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-cY66LlL4uEWC5SoN .cluster text{fill:#333;}#mermaid-svg-cY66LlL4uEWC5SoN .cluster span{color:#333;}#mermaid-svg-cY66LlL4uEWC5SoN div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-cY66LlL4uEWC5SoN .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-cY66LlL4uEWC5SoN rect.text{fill:none;stroke-width:0;}#mermaid-svg-cY66LlL4uEWC5SoN .icon-shape,#mermaid-svg-cY66LlL4uEWC5SoN .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cY66LlL4uEWC5SoN .icon-shape p,#mermaid-svg-cY66LlL4uEWC5SoN .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-cY66LlL4uEWC5SoN .icon-shape .label rect,#mermaid-svg-cY66LlL4uEWC5SoN .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cY66LlL4uEWC5SoN .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-cY66LlL4uEWC5SoN .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-cY66LlL4uEWC5SoN :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
有效
无效
原始数据
数据验证
计算平均值
错误处理
计算中位数
比较分析
生成报告
记录错误
重新采集
数组维度处理技巧 📐
NumPy的强大之处在于它能够优雅地处理多维数组:
三维数组统计
# 创建三维数组模拟多个实验的数据
# 形状: (实验次数, 样本数, 特征数)
experimental_data = np.random.rand(3, 100, 5) * 100
print("=== 多维实验数据分析 ===")
print(f"数据形状: {experimental_data.shape}")
# 计算每个实验的总体平均值
experiment_means = np.mean(experimental_data, axis=(1, 2))
print(f"各实验平均值: {experiment_means}")
# 计算每个样本的平均值(跨特征和实验)
sample_means = np.mean(experimental_data, axis=(0, 2))
print(f"前10个样本的平均值: {sample_means[:10]}")
# 计算每个特征的中位数
feature_medians = np.median(experimental_data, axis=(0, 1))
print(f"各特征中位数: {feature_medians}")
条件统计计算
# 在特定条件下计算统计量
temperature_data = np.random.normal(25, 5, 365) # 一年的温度数据
# 只计算夏季月份的统计数据(假设6-8月)
summer_indices = np.arange(151, 243) # 第152天到第243天
summer_temps = temperature_data[summer_indices]
print("=== 季节性温度分析 ===")
print(f"全年平均温度: {np.mean(temperature_data):.2f}°C")
print(f"夏季平均温度: {np.mean(summer_temps):.2f}°C")
print(f"全年温度中位数: {np.median(temperature_data):.2f}°C")
print(f"夏季温度中位数: {np.median(summer_temps):.2f}°C")
# 找出极端高温天数
hot_days = temperature_data[temperature_data > np.mean(temperature_data) + 2*np.std(temperature_data)]
print(f"极端高温天数: {len(hot_days)} 天")
自定义统计函数 🛠️
有时候内置函数无法满足特殊需求,我们可以创建自定义统计函数:
加权平均值
def weighted_mean(values, weights):
"""计算加权平均值"""
return np.sum(values * weights) / np.sum(weights)
# 示例:学生成绩加权计算
subjects = ['数学', '英语', '物理', '化学']
scores = np.array([95, 88, 92, 85])
weights = np.array([0.3, 0.25, 0.25, 0.2]) # 各科目权重
print("=== 加权成绩计算 ===")
for subject, score, weight in zip(subjects, scores, weights):
print(f"{subject}: {score}分 (权重: {weight})")
simple_mean = np.mean(scores)
weighted_avg = weighted_mean(scores, weights)
print(f"简单平均分: {simple_mean:.2f}")
print(f"加权平均分: {weighted_avg:.2f}")
截尾平均值
def trimmed_mean(data, trim_percent=0.1):
"""计算截尾平均值(去除极值后的平均值)"""
data_sorted = np.sort(data)
n = len(data_sorted)
trim_count = int(n * trim_percent)
if trim_count > 0:
trimmed_data = data_sorted[trim_count:–trim_count]
else:
trimmed_data = data_sorted
return np.mean(trimmed_data)
# 测试截尾平均值
noisy_data = np.concatenate([
np.array([1, 2]), # 极低值
np.random.normal(50, 5, 96),
np.array([98, 99]) # 极高值
])
print("=== 截尾平均值对比 ===")
print(f"原始数据: {noisy_data[:10]}…{noisy_data[–10:]}")
print(f"普通平均值: {np.mean(noisy_data):.2f}")
print(f"中位数: {np.median(noisy_data):.2f}")
print(f"10%截尾平均值: {trimmed_mean(noisy_data, 0.1):.2f}")
print(f"20%截尾平均值: {trimmed_mean(noisy_data, 0.2):.2f}")
与其他统计库的集成 🔄
NumPy可以很好地与其他统计和数据分析库配合使用:
与Pandas集成
import pandas as pd
# 创建DataFrame进行统计分析
df = pd.DataFrame({
'产品A': np.random.normal(100, 15, 50),
'产品B': np.random.normal(120, 20, 50),
'产品C': np.random.normal(80, 10, 50)
})
print("=== Pandas DataFrame统计 ===")
print(df.head())
# 使用NumPy函数处理DataFrame
print(f"产品A平均值: {np.mean(df['产品A']):.2f}")
print(f"产品B中位数: {np.median(df['产品B']):.2f}")
# 跨产品的统计
all_products = df.values.flatten()
print(f"所有产品平均值: {np.mean(all_products):.2f}")
print(f"所有产品中位数: {np.median(all_products):.2f}")
与SciPy结合进行统计检验
from scipy import stats
# 生成两组数据进行比较
group1 = np.random.normal(100, 15, 30)
group2 = np.random.normal(105, 15, 30)
print("=== 统计显著性检验 ===")
print(f"组1平均值: {np.mean(group1):.2f}")
print(f"组2平均值: {np.mean(group2):.2f}")
# 进行t检验
t_stat, p_value = stats.ttest_ind(group1, group2)
print(f"t统计量: {t_stat:.4f}")
print(f"p值: {p_value:.4f}")
if p_value < 0.05:
print("✅ 两组数据存在显著差异")
else:
print("❌ 两组数据无显著差异")
实时数据流处理 📡
在现代应用中,经常需要处理实时到达的数据流:
class StreamingStats:
"""实时统计计算器"""
def __init__(self):
self.count = 0
self.sum_values = 0.0
self.sorted_values = []
def add_value(self, value):
"""添加新值并更新统计"""
self.count += 1
self.sum_values += value
# 保持有序列表用于中位数计算
import bisect
bisect.insort(self.sorted_values, value)
def get_mean(self):
"""获取当前平均值"""
if self.count == 0:
return 0
return self.sum_values / self.count
def get_median(self):
"""获取当前中位数"""
if self.count == 0:
return 0
mid = self.count // 2
if self.count % 2 == 0:
return (self.sorted_values[mid–1] + self.sorted_values[mid]) / 2
else:
return self.sorted_values[mid]
# 模拟实时数据流
stream_stats = StreamingStats()
sensor_data = np.random.normal(25, 2, 100) # 温度传感器数据
print("=== 实时数据流统计 ===")
for i, value in enumerate(sensor_data):
stream_stats.add_value(value)
if (i + 1) % 20 == 0: # 每20个数据点输出一次统计
current_mean = stream_stats.get_mean()
current_median = stream_stats.get_median()
print(f"数据点 {i+1}: 平均值={current_mean:.2f}, 中位数={current_median:.2f}")
最佳实践总结 📋
基于以上讨论,以下是使用NumPy进行平均值和中位数计算的最佳实践:
性能优化建议
# 性能对比示例
large_data = np.random.rand(1000000)
# 方法1:直接计算
%timeit np.mean(large_data)
# 方法2:指定数据类型
%timeit np.mean(large_data, dtype=np.float32)
# 方法3:使用预分配数组
result = np.empty(1)
%timeit np.mean(large_data, out=result)
代码质量保证
def robust_mean(data, handle_nan=True):
"""
计算数组平均值的安全版本
参数:
data: 输入数据数组
handle_nan: 是否处理NaN值
返回:
float: 平均值或NaN
异常:
ValueError: 当输入为空数组时
"""
if len(data) == 0:
raise ValueError("输入数组不能为空")
if handle_nan:
return np.nanmean(data)
else:
return np.mean(data)
# 测试健壮性函数
test_cases = [
np.array([1, 2, 3, 4, 5]),
np.array([1, 2, np.nan, 4, 5]),
np.array([]) # 这个会抛出异常
]
for i, case in enumerate(test_cases[:–1]): # 排除最后一个空数组测试
try:
result = robust_mean(case)
print(f"测试案例 {i+1}: {result}")
except Exception as e:
print(f"测试案例 {i+1} 出错: {e}")
结语与展望 🌟
通过本文的详细介绍,我们全面了解了如何使用NumPy计算数组的平均值和中位数。从基础概念到高级应用,从性能优化到错误处理,我们探索了这一重要统计功能的各个方面。
NumPy的统计函数不仅功能强大,而且使用简便,是每个数据科学家和工程师都应该掌握的基础技能。随着数据量的不断增长和计算需求的日益复杂,熟练运用这些工具将帮助我们在数据分析的道路上走得更远。
在未来的学习中,建议继续探索NumPy提供的其他统计函数,如标准差、方差、相关系数等,并结合实际项目进行练习。同时,也要关注NumPy社区的发展动态,及时了解新特性和最佳实践。
记住,统计学不仅仅是数字的游戏,更是理解和解释数据背后故事的艺术。掌握好这些基础工具,你就能更好地从数据中发现价值,做出明智的决策。
想要了解更多关于NumPy的详细信息,可以访问NumPy官方文档。对于统计学理论知识的深入学习,推荐参考Statistics How To网站。
如果你正在寻找更多Python数据分析资源,Python Data Science Handbook是一个非常好的免费在线资源。
对于机器学习和深度学习领域的进一步学习,Scikit-learn和TensorFlow都是值得深入了解的重要工具。
🙌 感谢你读到这里! 🔍 技术之路没有捷径,但每一次阅读、思考和实践,都在悄悄拉近你与目标的距离。 💡 如果本文对你有帮助,不妨 👍 点赞、📌 收藏、📤 分享 给更多需要的朋友! 💬 欢迎在评论区留下你的想法、疑问或建议,我会一一回复,我们一起交流、共同成长 🌿 🔔 关注我,不错过下一篇干货!我们下期再见!✨

