仅用Numpy处理太阳黑子数据:数组填充及时间区间高效统计问题
太阳黑子数据的世纪/十年区间统计解决方案
一、解决世纪统计数组被覆盖的问题
你遇到的核心问题是循环中数组索引使用错误,导致每次循环都覆盖了整个数组,而非对应行。以下是正确的实现逻辑:
步骤与示例代码
import numpy as np # 读取数据(假设CSV第一列是年份,第二列是太阳黑子数) data = np.loadtxt('sunspots.csv', delimiter=',', skiprows=1) year = data[:, 0].astype(int) sunspots = data[:, 1] # 定义各世纪的时间区间 centuries = [(1700, 1799), (1800, 1899), (1900, 2019)] # 初始化统计数组:每行对应一个世纪,列依次为最小值、最大值、总和、平均值、标准差 cent_stats = np.zeros((len(centuries), 5)) for idx, (start_year, end_year) in enumerate(centuries): # 筛选当前世纪的数据 mask = (year >= start_year) & (year <= end_year) current_data = sunspots[mask] # 按索引赋值,避免覆盖整个数组 cent_stats[idx, 0] = np.min(current_data) cent_stats[idx, 1] = np.max(current_data) cent_stats[idx, 2] = np.sum(current_data) cent_stats[idx, 3] = np.mean(current_data) cent_stats[idx, 4] = np.std(current_data) # 验证结果 print("世纪统计结果(Min | Max | Sum | Mean | Std):") print(cent_stats)
问题根源
如果之前你直接用cent_stats = [min_val, max_val, ...]而非cent_stats[idx] = ...,会导致每次循环都替换整个数组;或者未用enumerate获取索引,导致所有行都被最后一次循环的结果覆盖。
二、高效处理十年区间统计
无需逐个创建变量,可通过年份分组实现批量统计:
方法1:按年份整除10生成分组标签
# 生成十年组标签(如1700-1709对应170,1710-1719对应171) decade_groups = year // 10 # 获取唯一的十年组并排序 unique_decades = np.sort(np.unique(decade_groups)) # 初始化十年统计数组 dec_stats = np.zeros((len(unique_decades), 5)) for idx, decade in enumerate(unique_decades): mask = decade_groups == decade current_data = sunspots[mask] dec_stats[idx] = [ np.min(current_data), np.max(current_data), np.sum(current_data), np.mean(current_data), np.std(current_data) ] # 格式化输出结果 decade_labels = [f"{d*10}-{d*10+9}" for d in unique_decades] print("\n十年统计结果:") for label, stats in zip(decade_labels, dec_stats): print(f"{label}: Min={stats[0]:.2f}, Max={stats[1]:.2f}, Sum={stats[2]:.0f}, Mean={stats[3]:.2f}, Std={stats[4]:.2f}")
方法2:年份连续时直接分割数组
如果数据年份是连续的1700-2019(共320年),可直接按每10年分割:
# 分割成32个十年区间的数组 split_data = np.array_split(sunspots, 32) # 批量计算统计指标 dec_stats = np.array([ [np.min(d), np.max(d), np.sum(d), np.mean(d), np.std(d)] for d in split_data ])
内容的提问来源于stack exchange,提问作者yakubs
相关产品推荐
相关产品推荐

