我将为您展示NumPy轴方向统计在多维数据分析中的应用,通过生活场景案例来理解轴的概念。
一、二维数据生活场景案例
案例1:学生成绩分析(axis=0按科目,axis=1按学生)
python
import numpy as np
# 场景:5名学生3门科目的考试成绩
# 行:学生(0-4),列:科目(语文、数学、英语)
scores = np.array([
[85, 92, 78], # 学生0
[90, 88, 95], # 学生1
[76, 85, 82], # 学生2
[92, 95, 88], # 学生3
[88, 90, 85] # 学生4
])
print("=== 学生成绩分析 ===")
print("原始成绩表:")
print(scores)
# axis=0: 按列方向统计(垂直方向) -> 分析各科目整体情况
subject_means = np.mean(scores, axis=0) # 每列求平均,得到各科目的平均分
subject_max = np.max(scores, axis=0) # 每列求最大,得到各科目的最高分
print("\n【axis=0 按科目统计】")
print(f"各科目平均分(语文、数学、英语): {subject_means}")
print(f"各科目最高分: {subject_max}")
# axis=1: 按行方向统计(水平方向) -> 分析各学生整体情况
student_means = np.mean(scores, axis=1) # 每行求平均,得到各学生的平均分
student_total = np.sum(scores, axis=1) # 每行求和,得到各学生的总分
print("\n【axis=1 按学生统计】")
print(f"学生平均分: {student_means}")
print(f"学生总分: {student_total}")
案例2:店铺月度销售额(axis=0按月份,axis=1按店铺)
python
import numpy as np
# 场景:3家店铺4个月的销售额(万元)
# 行:月份(1-4月),列:店铺(A、B、C)
sales = np.array([
[12.5, 15.2, 10.8], # 1月
[13.2, 14.8, 11.5], # 2月
[14.0, 16.5, 12.0], # 3月
[15.5, 17.0, 13.2] # 4月
])
print("\n=== 店铺月度销售分析 ===")
print("原始销售数据:")
print(sales)
# axis=0: 按列统计 -> 分析各店铺的销售趋势
store_avg = np.mean(sales, axis=0) # 每列平均,得到各店铺月平均销售额
store_total = np.sum(sales, axis=0) # 每列求和,得到各店铺总销售额
print("\n【axis=0 按店铺统计】")
print(f"各店铺月平均销售额: {store_avg}")
print(f"各店铺总销售额: {store_total}")
# axis=1: 按行统计 -> 分析各月份的销售情况
month_avg = np.mean(sales, axis=1) # 每行平均,得到每月平均销售额
month_total = np.sum(sales, axis=1) # 每行求和,得到每月总销售额
print("\n【axis=1 按月份统计】")
print(f"每月平均销售额(1-4月): {month_avg}")
print(f"每月总销售额(1-4月): {month_total}")
案例3:运动员成绩记录(axis=0按轮次,axis=1按运动员)
python
import numpy as np
# 场景:4名运动员3轮比赛成绩
# 行:轮次(第1-3轮),列:运动员(甲、乙、丙、丁)
records = np.array([
[9.8, 9.5, 9.7, 9.6], # 第1轮
[9.9, 9.6, 9.8, 9.5], # 第2轮
[9.7, 9.8, 9.9, 9.7] # 第3轮
])
print("\n=== 运动员成绩分析 ===")
print("原始成绩数据:")
print(records)
# axis=0: 按列统计 -> 分析每位运动员的稳定性
athlete_mean = np.mean(records, axis=0) # 各运动员平均分
athlete_std = np.std(records, axis=0) # 各运动员标准差(稳定性)
print("\n【axis=0 按运动员统计】")
print(f"运动员平均分: {athlete_mean}")
print(f"运动员稳定性(标准差越小越稳定): {athlete_std}")
# axis=1: 按行统计 -> 分析每轮比赛的整体水平
round_mean = np.mean(records, axis=1) # 每轮平均分
round_best = np.max(records, axis=1) # 每轮最好成绩
print("\n【axis=1 按轮次统计】")
print(f"每轮平均分: {round_mean}")
print(f"每轮最好成绩: {round_best}")
案例4:超市库存管理(axis=0按商品,axis=1按仓库)
python
import numpy as np
# 场景:5种商品在3个仓库的库存量
# 行:商品(饮料、零食、日用品、生鲜、调料),列:仓库(1号、2号、3号)
inventory = np.array([
[120, 85, 150], # 饮料
[200, 180, 220], # 零食
[80, 95, 70], # 日用品
[50, 45, 60], # 生鲜
[100, 110, 90] # 调料
])
print("\n=== 超市库存分析 ===")
print("原始库存数据:")
print(inventory)
# axis=0: 按列统计 -> 分析各仓库的库存情况
warehouse_total = np.sum(inventory, axis=0) # 各仓库总库存
warehouse_avg = np.mean(inventory, axis=0) # 各仓库平均库存
print("\n【axis=0 按仓库统计】")
print(f"各仓库总库存: {warehouse_total}")
print(f"各仓库平均库存: {warehouse_avg}")
# axis=1: 按行统计 -> 分析各商品的库存分布
product_total = np.sum(inventory, axis=1) # 各商品总库存
product_max = np.max(inventory, axis=1) # 各商品最大库存仓库的库存量
print("\n【axis=1 按商品统计】")
print(f"各商品总库存: {product_total}")
print(f"各商品最大库存: {product_max}")
案例5:天气数据统计(axis=0按城市,axis=1按时间)
python
import numpy as np
# 场景:3个城市7天的温度数据(摄氏度)
# 行:城市(北京、上海、广州),列:星期(周一至周日)
temperatures = np.array([
[18, 20, 22, 21, 19, 18, 17], # 北京
[22, 23, 24, 23, 22, 21, 20], # 上海
[25, 26, 26, 25, 24, 24, 23] # 广州
])
print("\n=== 城市天气分析 ===")
print("原始温度数据:")
print(temperatures)
# axis=0: 按列统计 -> 分析每天各城市的温度情况
daily_avg = np.mean(temperatures, axis=0) # 每天的平均温度
daily_range = np.ptp(temperatures, axis=0) # 每天的温差(最大值-最小值)
print("\n【axis=0 按天统计】")
print(f"每日平均温度: {daily_avg}")
print(f"每日温差: {daily_range}")
# axis=1: 按行统计 -> 分析各城市的温度特征
city_avg = np.mean(temperatures, axis=1) # 各城市平均温度
city_max = np.max(temperatures, axis=1) # 各城市最高温度
city_min = np.min(temperatures, axis=1) # 各城市最低温度
print("\n【axis=1 按城市统计】")
print(f"城市平均温度: {city_avg}")
print(f"城市最高温度: {city_max}")
print(f"城市最低温度: {city_min}")
二、三维数据生活场景案例
案例6:多班级多科目成绩(axis=0按班级,axis=1按学生,axis=2按科目)
python
import numpy as np
# 场景:2个班级,每个班级3名学生,4门科目的成绩
# 维度:[班级, 学生, 科目]
scores_3d = np.array([
# 班级1
[[85, 92, 78, 88], # 学生1: 语、数、英、理
[90, 88, 95, 85], # 学生2
[76, 85, 82, 90]], # 学生3
# 班级2
[[88, 90, 85, 92], # 学生4
[92, 95, 88, 86], # 学生5
[85, 87, 90, 89]] # 学生6
])
print("\n=== 三维成绩分析 ===")
print("原始三维成绩数据:")
print(scores_3d)
# axis=0: 按班级统计(跨班级比较)
class_avg = np.mean(scores_3d, axis=0) # 每个班级的学生-科目矩阵的平均
print("\n【axis=0 按班级统计】各班级学生平均成绩:")
print(class_avg)
# axis=1: 按学生统计(每个班级内分析学生)
student_avg = np.mean(scores_3d, axis=1) # 每个班级各学生的平均分
print("\n【axis=1 按学生统计】各班级学生平均分:")
print(student_avg)
# axis=2: 按科目统计(分析各科目成绩)
subject_avg = np.mean(scores_3d, axis=2) # 每个班级各科目的平均分
print("\n【axis=2 按科目统计】各班级科目平均分:")
print(subject_avg)
案例7:电商销售数据(年-月-日)
python
import numpy as np
# 场景:2年,每年4个季度,每个季度3个月的销售数据
# 维度:[年份, 季度, 月份]
sales_3d = np.array([
# 第1年
[[120, 135, 142], # Q1: 1-3月
[150, 165, 170], # Q2: 4-6月
[180, 190, 185], # Q3: 7-9月
[200, 210, 205]], # Q4: 10-12月
# 第2年
[[130, 145, 155], # Q1
[160, 175, 180], # Q2
[190, 200, 195], # Q3
[210, 220, 215]] # Q4
])
print("\n=== 电商销售分析 ===")
print("原始三维销售数据(年×季度×月):")
print(sales_3d)
# axis=0: 按年统计
yearly_sales = np.sum(sales_3d, axis=(1, 2)) # 合并季度和月份维度
print("\n【axis=0 按年统计】每年总销售额:")
print(f"第1年: {yearly_sales[0]}, 第2年: {yearly_sales[1]}")
# axis=1: 按季度统计
quarterly_avg = np.mean(sales_3d, axis=1) # 各年各季度的平均月销售额
print("\n【axis=1 按季度统计】各年各季度平均月销售额:")
print(quarterly_avg)
# axis=2: 按月份位置统计(分析每个季度中不同月份的销售规律)
month_pattern = np.mean(sales_3d, axis=(0, 1)) # 跨年跨季度平均
print("\n【axis=2 按月份位置统计】季度内各月平均销售额:")
print(f"第1月: {month_pattern[0]:.1f}, 第2月: {month_pattern[1]:.1f}, 第3月: {month_pattern[2]:.1f}")
案例8:多城市多站点空气质量
python
import numpy as np
# 场景:3个城市,每个城市4个监测站,记录5天的PM2.5数据
# 维度:[城市, 站点, 天数]
air_quality = np.array([
# 北京
[[35, 42, 38, 45, 40], # 站点1
[38, 45, 42, 48, 43], # 站点2
[32, 38, 35, 40, 37], # 站点3
[40, 48, 45, 50, 44]], # 站点4
# 上海
[[28, 35, 32, 38, 33], # 站点1
[30, 38, 35, 40, 36], # 站点2
[25, 32, 30, 35, 31], # 站点3
[32, 40, 38, 42, 39]], # 站点4
# 广州
[[22, 28, 25, 30, 26], # 站点1
[25, 30, 28, 32, 29], # 站点2
[20, 25, 22, 28, 24], # 站点3
[28, 32, 30, 35, 33]] # 站点4
])
print("原始数据结构:")
print(f"数组形状: {air_quality.shape}") # (3, 4, 5)
print("含义: 3个城市 × 4个站点 × 5天")
# axis=0: 按城市统计
city_avg = np.mean(air_quality, axis=(1, 2)) # 合并站点和天数
print("\n【axis=0 按城市统计】各城市平均PM2.5:")
for i, city in enumerate(['北京', '上海', '广州']):
print(f"{city}: {city_avg[i]:.1f}")
# axis=1: 按监测站统计
station_avg = np.mean(air_quality, axis=1) # 对站点维度求平均
print("\n【axis=1 按监测站统计】各城市各站点的平均PM2.5:")
print("形状:", station_avg.shape) # (3, 5) - 每个城市各天的平均
print("北京各天平均:", station_avg[0])
print("上海各天平均:", station_avg[1])
print("广州各天平均:", station_avg[2])
# axis=2: 按天数统计
daily_avg = np.mean(air_quality, axis=2) # 对天数维度求平均
print("\n【axis=2 按天数统计】各城市各站点的平均PM2.5:")
print("形状:", daily_avg.shape) # (3, 4) - 每个城市各站点的平均
print("北京各站点平均:", daily_avg[0])
print("上海各站点平均:", daily_avg[1])
print("广州各站点平均:", daily_avg[2])
# 修正:取出第3天的数据(注意:天数索引从0开始,第3天对应索引2)
print("\n【修正】取出第3天的数据(各城市各站点的PM2.5值):")
# 方法1:使用切片取第3天的数据
day_3_data = air_quality[:, :, 2] # 取所有城市、所有站点的第3天数据
print("第3天数据形状:", day_3_data.shape) # (3, 4)
print("第3天数据:")
print("北京各站点:", day_3_data[0])
print("上海各站点:", day_3_data[1])
print("广州各站点:", day_3_data[2])
# 方法2:如果要显示特定城市特定站点的第3天数据
print("\n北京站点1第3天PM2.5:", air_quality[0, 0, 2]) # 北京(0),站点1(0),第3天(2)
print("上海站点2第3天PM2.5:", air_quality[1, 1, 2]) # 上海(1),站点2(1),第3天(2)
print("广州站点3第3天PM2.5:", air_quality[2, 2, 2]) # 广州(2),站点3(2),第3天(2)
# 更多示例:不同维度的统计分析
print("\n=== 多维度统计分析 ===")
# 1. 各城市每天的空气质量(跨站点平均)
city_daily = np.mean(air_quality, axis=1) # 对站点求平均
print("\n1. 各城市每天的平均PM2.5(跨站点平均):")
print("形状:", city_daily.shape) # (3, 5)
print(f"北京5天数据: {city_daily[0]}")
print(f"上海5天数据: {city_daily[1]}")
print(f"广州5天数据: {city_daily[2]}")
# 2. 各站点5天的平均(跨城市、跨天)
site_pattern = np.mean(air_quality, axis=(0, 2)) # 合并城市和天数
print("\n2. 各监测站类型的平均PM2.5(跨所有城市和天数):")
print("形状:", site_pattern.shape) # (4,)
print(f"站点1平均: {site_pattern[0]:.1f}")
print(f"站点2平均: {site_pattern[1]:.1f}")
print(f"站点3平均: {site_pattern[2]:.1f}")
print(f"站点4平均: {site_pattern[3]:.1f}")
# 3. 找出每个城市空气质量最好的站点
best_station_per_city = np.argmin(daily_avg, axis=1) # 对站点维度找最小值索引
print("\n3. 各城市空气质量最好的站点(PM2.5最低):")
for i, city in enumerate(['北京', '上海', '广州']):
print(f"{city}: 站点{best_station_per_city[i]+1} (PM2.5: {daily_avg[i, best_station_per_city[i]]:.1f})")
# 4. 找出每个城市空气质量最差的一天
worst_day_per_city = np.argmax(city_daily, axis=1) # 对天数维度找最大值索引
print("\n4. 各城市空气质量最差的一天:")
for i, city in enumerate(['北京', '上海', '广州']):
print(f"{city}: 第{worst_day_per_city[i]+1}天 (PM2.5: {city_daily[i, worst_day_per_city[i]]:.1f})")
案例9:视频平台观看数据
python
import numpy as np
# 场景:2个视频类别,每个类别3个视频,记录7天的观看次数(万次)
# 维度:[类别, 视频, 天数]
views_3d = np.array([
# 娱乐类
[[15, 18, 20, 22, 19, 16, 14], # 视频1
[25, 28, 30, 32, 29, 26, 24], # 视频2
[10, 12, 15, 18, 16, 14, 12]], # 视频3
# 教育类
[[8, 9, 12, 15, 14, 11, 10], # 视频4
[12, 15, 18, 20, 19, 16, 14], # 视频5
[5, 6, 8, 10, 9, 7, 6]] # 视频6
])
print("\n=== 视频观看数据分析 ===")
print("原始观看数据:")
# axis=0: 按类别统计
category_total = np.sum(views_3d, axis=(1, 2)) # 合并视频和天数
print("\n【axis=0 按类别统计】各类别总观看量:")
print(f"娱乐类: {category_total[0]}万, 教育类: {category_total[1]}万")
# axis=1: 按视频统计
video_avg = np.mean(views_3d, axis=1) # 各类别各视频的平均观看量
print("\n【axis=1 按视频统计】各类别视频平均观看量:")
print(video_avg)
# axis=2: 按天数统计(分析周趋势)
weekly_pattern = np.mean(views_3d, axis=(0, 1)) # 跨类别跨视频平均
print("\n【axis=2 按天数统计】一周内每天平均观看量:")
days = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']
for day, value in zip(days, weekly_pattern):
print(f"{day}: {value:.1f}万")
案例10:医院多科室多医生工作量
python
import numpy as np
# 场景:3个科室,每个科室4名医生,记录5天的工作量(接诊人数)
# 维度:[科室, 医生, 天数]
workload = np.array([
# 内科
[[12, 15, 14, 16, 13], # 医生1
[10, 12, 11, 14, 12], # 医生2
[15, 18, 16, 19, 17], # 医生3
[8, 10, 9, 11, 10]], # 医生4
# 外科
[[20, 22, 21, 24, 20], # 医生1
[18, 20, 19, 22, 19], # 医生2
[22, 25, 23, 26, 24], # 医生3
[15, 18, 16, 19, 17]], # 医生4
# 儿科
[[25, 28, 26, 30, 27], # 医生1
[22, 25, 23, 27, 24], # 医生2
[28, 30, 29, 32, 30], # 医生3
[20, 22, 21, 24, 22]] # 医生4
])
print("\n=== 医院工作量分析 ===")
print("原始工作量数据:")
# axis=0: 按科室统计
dept_total = np.sum(workload, axis=(1, 2)) # 合并医生和天数
dept_avg = np.mean(workload, axis=(1, 2))
print("\n【axis=0 按科室统计】")
depts = ['内科', '外科', '儿科']
for i, dept in enumerate(depts):
print(f"{dept}: 总接诊{dept_total[i]}人, 日均{dept_avg[i]:.1f}人")
# axis=1: 按医生统计
doctor_avg = np.mean(workload, axis=1) # 各科室各医生的平均
print("\n【axis=1 按医生统计】各科室医生的日均接诊量:")
print(doctor_avg)
# axis=2: 按天数统计
daily_load = np.sum(workload, axis=(0, 1)) # 合并科室和医生
print("\n【axis=2 按天数统计】全院每日总接诊量:")
for day, load in enumerate(daily_load, 1):
print(f"第{day}天: {load}人")
三、开发思路总结
1. 二维数据分析思路
1. 数据组织:确定行和列代表的意义
- 行通常代表个体(学生、商品、城市)
- 列通常代表属性(科目、时间、仓库)
2. 轴选择原则:
- axis=0:沿行的方向移动,对列进行操作(垂直方向)
* 适用于:统计各列特征(不同属性的对比)
- axis=1:沿列的方向移动,对行进行操作(水平方向)
* 适用于:统计各行特征(不同个体的对比)
3. 应用场景:
- 教育:学生成绩分析
- 零售:销售数据分析
- 体育:运动员表现分析
- 库存:商品库存管理
- 气象:天气数据分析
2. 三维数据分析思路
1. 维度理解:
- 第0轴:最外层,通常代表大类(班级、年份、城市)
- 第1轴:中间层,通常代表子类(学生、季度、站点)
- 第2轴:最内层,通常代表具体数据(科目、月份、天数)
2. 轴选择策略:
- axis=0:分析大类特征(跨类别比较)
- axis=1:分析子类特征(类别内比较)
- axis=2:分析细节特征(时间序列、属性分布)
3. 高级操作:
- 多轴合并:axis=(1,2) 合并子维度和细节维度
- 切片操作:保留特定维度进行分析
- 广播机制:不同维度数据的运算
4. 数据透视思维:
- 从不同角度观察数据
- 理解维度层次关系
- 选择合适统计方法
3. 轴方向记忆技巧
【二维数据】
axis=0:向下操作(列方向) → "0竖"(垂直)
axis=1:向右操作(行方向) → "1横"(水平)
【三维数据】
axis=0:跨"面"操作 → 不同平面的比较
axis=1:跨"行"操作 → 平面内行的比较
axis=2:跨"列"操作 → 平面内列的比较
记忆口诀:
"0外1中2内层,维度层次要分清
求和平均按轴算,数据透视显神通"
这些案例展示了NumPy轴方向统计在实际生活中的应用,通过理解轴的概念,可以灵活地从不同维度分析数据,发现数据背后的规律和 insights。