首页
统计
关于
Search
1
Sealos3.0离线部署K8s集群
1,308 阅读
2
类的加载
864 阅读
3
Spring Cloud OAuth2.0
857 阅读
4
SpringBoot自动装配原理
747 阅读
5
集合不安全问题
645 阅读
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Canvas
Linux
容器
Docker
Containerd
Podman
Kubernetes
Python
FastApi
OpenCV
数据分析
牛牛生活
登录
Search
标签搜索
Java
CSS
mysql
RabbitMQ
JavaScript
Redis
OpenCV
JVM
Mybatis-Plus
Camunda
多线程
CSS3
Python
Canvas
Spring Cloud
注解和反射
Activiti
工作流
SpringBoot
ndarray
蘇阿細
累计撰写
452
篇文章
累计收到
4
条评论
首页
栏目
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Canvas
Linux
容器
Docker
Containerd
Podman
Kubernetes
Python
FastApi
OpenCV
数据分析
牛牛生活
页面
统计
关于
搜索到
47
篇与
的结果
2025-12-08
二、数据分析 - seaborn - 案例
1. 房地产市场洞察与数据评估(1)导入依赖(2)导入数据(3)数据概览(4)数据清洗(5)新数据特征构造(6)问题分析及可视化import numpy as np import matplotlib.pyplot as plt import pandas as pd import seaborn as sns import datetime from matplotlib import rcParams rcParams['font.family'] = 'Microsoft YaHei'df = pd.read_csv('static/2_pandas/data/house_sales.csv', encoding='utf-8') print("总记录数:", len(df)) print("字段数数:", len(df.columns)) print(df.head(10)) print() df.info() 总记录数: 106118 字段数数: 12 city address area floor name price province \ 0 合肥 龙岗-临泉东路和王岗大道交叉口东南角 90㎡ 中层(共18层) 圣地亚哥 128万 安徽 1 合肥 龙岗-临泉东路和王岗大道交叉口东南角 90㎡ 中层(共18层) 圣地亚哥 128万 安徽 2 合肥 生态公园-淮海大道与大众路交口 95㎡ 中层(共18层) 正荣·悦都荟 132万 安徽 3 合肥 生态公园-淮海大道与大众路交口 95㎡ 中层(共18层) 正荣·悦都荟 132万 安徽 4 合肥 撮镇-文一名门金隅裕溪路与东风大道交口 37㎡ 中层(共22层) 文一名门金隅 32万 安徽 5 合肥 撮镇-文一名门金隅裕溪路与东风大道交口 37㎡ 中层(共22层) 文一名门金隅 32万 安徽 6 合肥 龙岗-长江东路与和县里交口 50㎡ 高层(共30层) 柏庄金座 46万 安徽 7 合肥 龙岗-长江东路与和县里交口 50㎡ 高层(共30层) 柏庄金座 46万 安徽 8 合肥 新亚汽车站-张洼路与临泉路交汇处向北100米(原红星机械 120㎡ 中层(共27层) 天目未来 158万 安徽 9 合肥 新亚汽车站-张洼路与临泉路交汇处向北100米(原红星机械 120㎡ 中层(共27层) 天目未来 158万 安徽 rooms toward unit year \ 0 3室2厅 南北向 14222元/㎡ 2013年建 1 3室2厅 南北向 14222元/㎡ 2013年建 2 3室2厅 南向 13895元/㎡ 2019年建 3 3室2厅 南向 13895元/㎡ 2019年建 4 2室1厅 南北向 8649元/㎡ 2017年建 5 2室1厅 南北向 8649元/㎡ 2017年建 6 2室1厅 南向 9200元/㎡ 2019年建 7 2室1厅 南向 9200元/㎡ 2019年建 8 4室2厅 南向 13167元/㎡ 2012年建 9 4室2厅 南向 13167元/㎡ 2012年建 origin_url 0 https://hf.esf.fang.com/chushou/3_404230646.htm 1 https://hf.esf.fang.com/chushou/3_404230646.htm 2 https://hf.esf.fang.com/chushou/3_404304901.htm 3 https://hf.esf.fang.com/chushou/3_404304901.htm 4 https://hf.esf.fang.com/chushou/3_404372096.htm 5 https://hf.esf.fang.com/chushou/3_404372096.htm 6 https://hf.esf.fang.com/chushou/3_398859799.htm 7 https://hf.esf.fang.com/chushou/3_398859799.htm 8 https://hf.esf.fang.com/chushou/3_381138154.htm 9 https://hf.esf.fang.com/chushou/3_381138154.htm <class 'pandas.core.frame.DataFrame'> RangeIndex: 106118 entries, 0 to 106117 Data columns (total 12 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 city 106118 non-null object 1 address 104452 non-null object 2 area 105324 non-null object 3 floor 104024 non-null object 4 name 105564 non-null object 5 price 105564 non-null object 6 province 106118 non-null object 7 rooms 104036 non-null object 8 toward 105240 non-null object 9 unit 105564 non-null object 10 year 57736 non-null object 11 origin_url 105564 non-null object dtypes: object(12) memory usage: 9.7+ MB# 数据清洗 df.drop(columns=['origin_url'], inplace=True) # df.head() # 缺失值处理 df.isna().sum() # 可选操作 df.dropna(inplace=True) # 删除重复数据 df.drop_duplicates(inplace=True) print(len(df)) 28104# 面积数据类型转换 df['area'] = df['area'].str.replace('㎡', '').astype(float) # 售价数据类型转换 df['price'] = df['price'].str.replace('万', '').astype(float) # 朝向数据类型转换 df['toward'] = df['toward'].astype('category') # 单价格数据类型转换 df['unit'] = df['unit'].str.replace('元/㎡', '').astype(float) # 年份格数据类型转换 df['year'] = df['year'].str.replace('年建', '').astype(int)# 异常值处理 # 房屋面积 df = df[(df['area'] > 20) & (df['area'] < 600)] # 价格 IQR Q1 = df['price'].quantile(0.25) Q3 = df['price'].quantile(0.75) IQR = Q3 - Q1 low_price = Q1 - 1.5 * IQR high_price = Q3 + 1.5 * IQR df = df[(df['price'] > low_price) & (df['price'] < high_price)]# 新数据特征构造 # 地区 district df['district'] = df['address'].str.split('-').str[0] # 楼层类型 floor_type df['floor_type'] = df['floor'].str.split('(').str[0].astype('category') # 是否是直辖市 zxs def is_zxs(city): if (city in ['北京', '上海', '天津', '重庆']): return True else: return False df['zxs'] = df['city'].apply(lambda x: 1 if is_zxs(x) else 0) # 卧室数 bedroom_num df['bedroom_num'] = df['rooms'].str.split('室').str[0].astype(int) # 客厅数量 living_room_num # df['living_room_num'] = df['rooms'].str.split('室').str[1].str.split('厅').str[0].fillna(0).astype(int) df['living_room_num'] = df['rooms'].str.extract(r'(\d+)厅').fillna(0).astype(int) # 房龄 house_age df['house_age'] = datetime.datetime.now().year - df['year'] # 价格区间 price_interval df['price_interval'] = pd.cut(df['price'], bins=3, labels=['低', '中', '高'])""" 分析一:哪些变量最影响房价?面积、楼层、房间数哪个因素影响最大? 分析主题:特征性相关 分析目标:各因素对房价的线性影响 分组字段:无 指标/方法:皮尔逊相关系数 """ # 选择数值型特征 # corr() 相关系数 corr = df[['price', 'area', 'unit', 'house_age']].corr() print("影响房价的因素:") print(corr['price'].sort_values(ascending=False)[1:]) # 相关性热力图 plt.figure(figsize=(10, 5)) sns.heatmap(corr, cmap='coolwarm') plt.title('房价因素热力图') plt.tight_layout()影响房价的因素: unit 0.742731 area 0.452523 house_age 0.091520 Name: price, dtype: float64""" 分析二:全国房价的总体分布,是否存在极端值 分析主题:描述性统计 分析字段:概览数值型字段的分布特征 分组字段:无 指标/方法:平均数/中位数/四分位数/标准差 """ print(df.describe()) # 房价分布直方图 plt.subplot() plt.hist(df['price'], bins=10) area price unit year zxs \ count 26135.000000 26135.000000 26135.000000 26135.000000 26135.000000 mean 103.755810 117.208370 11610.131012 2013.072240 0.008800 std 33.995994 60.967675 5824.245273 6.019342 0.093399 min 21.000000 9.000000 1000.000000 1976.000000 0.000000 25% 85.005000 72.000000 7587.000000 2011.000000 0.000000 50% 100.000000 103.000000 10312.000000 2015.000000 0.000000 75% 123.000000 150.000000 14184.000000 2017.000000 0.000000 max 470.000000 306.000000 85288.000000 2023.000000 1.000000 bedroom_num living_room_num house_age count 26135.000000 26135.000000 26135.000000 mean 2.714444 1.848556 11.927760 std 0.800768 0.407353 6.019342 min 0.000000 0.000000 2.000000 25% 2.000000 2.000000 8.000000 50% 3.000000 2.000000 10.000000 75% 3.000000 2.000000 14.000000 max 9.000000 12.000000 49.000000 (array([ 991., 4810., 6499., 4613., 3362., 2226., 1333., 1055., 691., 555.]), array([ 9. , 38.7, 68.4, 98.1, 127.8, 157.5, 187.2, 216.9, 246.6, 276.3, 306. ]), <BarContainer object of 10 artists>)sns.histplot(data=df, x='price', bins=10, kde=True)<Axes: xlabel='price', ylabel='Count'>""" 分析三:南北向是否比单一朝向贵?贵多少? 分析主题:朝向溢价 分析目标:评估不同朝向的价格差异 分组字段:toward 指标/方法:方差分析/多重比较 """ print(df['toward'].value_counts()) toward 南北向 14884 南向 8796 东南向 974 东向 419 北向 258 西南向 254 西向 161 东西向 151 西北向 133 东北向 105 Name: count, dtype: int64print(df.groupby('toward', observed=False).agg({ 'price': ['mean', 'median'], 'unit': 'median', 'house_age': 'mean' })) price unit house_age mean median median mean toward 东北向 114.555333 100.0 12198.0 12.609524 东南向 115.542608 105.0 10864.0 10.951745 东向 110.158568 95.0 11421.0 12.761337 东西向 98.935099 82.0 9000.0 15.490066 北向 92.527907 75.5 11698.0 13.108527 南北向 119.472147 104.5 10000.0 12.073703 南向 114.555016 103.0 10759.0 11.551160 西北向 119.107594 105.0 12290.0 13.473684 西南向 139.711811 138.4 13333.0 13.452756 西向 102.662298 86.0 12528.0 13.385093plt.figure(figsize=(10, 5)) sns.boxplot(data=df, x='toward', y='price') plt.tight_layout()
2025年12月08日
13 阅读
0 评论
0 点赞
2025-12-07
一、数据分析 - seaborn
# 安装依赖 pip install seaborn一、统计图import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from matplotlib import rcParams rcParams['font.family'] = 'Microsoft YaHei' # 设置图表大小 plt.figure(figsize=(10, 5)) # data penguins = pd.read_csv('static/2_pandas/data/penguins.csv') penguins.dropna(inplace=True) # penguins.head()1. 直方图sns.histplot(data=penguins, x='species') <Axes: xlabel='species', ylabel='Count'>2. 核密度估计图核密度估计图(KDE,Kernel Density Estimate Plot)用于显示数据分布,其通过平滑直方图的方法来估计数据的概率密度函数,使得分布图看起来更加连续、平滑。核密度估计是一种非参数方法,用于估计随机变量的概率密度函数。其基本思想是将每个数据点视为一个”核(高斯分布)“,然后将这些核的贡献相加以构成平滑的密度曲线。# 喙长度 - 核密度估计图 sns.kdeplot(data=penguins, x='bill_length_mm') <Axes: xlabel='bill_length_mm', ylabel='Density'>sns.histplot(data=penguins, x='bill_length_mm', kde=True) <Axes: xlabel='bill_length_mm', ylabel='Count'>3. 计数图计数图用于绘制分类变量的计数分布图,显示每个类别在数据集中出现的次数,可以快速了解类别的分布情况。# 不同岛屿的企鹅分布数量 sns.countplot(data=penguins, x='island') <Axes: xlabel='island', ylabel='count'>4. 散点图# x:体重,y:脚蹼长度 # hue参数可设置通过不同”分类“进行比对 sns.scatterplot(data=penguins, x='body_mass_g', y='flipper_length_mm', hue='sex') <Axes: xlabel='body_mass_g', ylabel='flipper_length_mm'>5. 蜂窝图# kind='hex' sns.jointplot(data=penguins, x='body_mass_g', y='flipper_length_mm', kind='hex') <seaborn.axisgrid.JointGrid at 0x239c7cddc40>6. 二维核密度估计图# 同时设置参数x和y sns.kdeplot(data=penguins, x='body_mass_g', y='flipper_length_mm') <Axes: xlabel='body_mass_g', ylabel='flipper_length_mm'># fill 填充 # cbar 颜色示意条 sns.kdeplot(data=penguins, x='body_mass_g', y='flipper_length_mm', fill=True, cbar=True) <Axes: xlabel='body_mass_g', ylabel='flipper_length_mm'>7. 条形图sns.barplot(data=penguins, x='species', y='bill_length_mm', estimator='mean', errorbar=None) <Axes: xlabel='species', ylabel='bill_length_mm'>8. 箱线图sns.boxplot(data=penguins, x='species', y='bill_length_mm') <Axes: xlabel='species', ylabel='bill_length_mm'>9. 小提琴图小提琴图(Violin Plot)是一种结合了箱线图和核密度估计图的可视化图表,用于展示数据的分布情况、集中趋势、散布情况以及异常值,不仅可以显示数据的基本统计量(中位数、四分位数等),还可以展示数据的概率密度。sns.violinplot(data=penguins, x='species', y='bill_length_mm') <Axes: xlabel='species', ylabel='bill_length_mm'>10. 成对关系图成对关系图是一种用于显示多个变量之间关系的可视化图表,其对角线上的图通常显示每个变量的分布,即单变量特性,其他位置的图用于展示所有变量的两两关系。sns.pairplot(penguins, hue='species') <seaborn.axisgrid.PairGrid at 0x239c979de20>
2025年12月07日
12 阅读
0 评论
0 点赞
2025-12-05
二、matplotlib - 统计图 - 案例
(1)温度、降水量分析import pandas as pd import matplotlib.pyplot as plt from matplotlib import rcParams rcParams['font.family'] = 'Microsoft YaHei' # data df = pd.read_csv('static/2_pandas/data/weather.csv') # print(df.head()) df['date'] = pd.to_datetime(df['date']) df = df[df['date'].dt.year == 2014] # 设置图表大小 plt.figure(figsize=(15, 10)) # 气温趋势变化图 plt.plot(df['date'], df['temp_max'], label='最高气温') plt.plot(df['date'], df['temp_min'], label='最低气温') plt.title('xxxx年气温变化趋势', fontsize=20) plt.legend(loc='upper left', fontsize='xx-large') plt.xlabel('日期', fontsize=16) plt.ylabel('温度', fontsize=16) plt.xticks(fontsize=15) plt.yticks(fontsize=15) plt.show()# 设置图表大小 plt.figure(figsize=(10, 5)) # 降水量直方图 data = df[df['date'].dt.year == 2014] plt.hist(data.precipitation, bins=5) plt.title('xxxx年降水量统计(直方图)', fontsize=16) plt.xlabel('降水量', fontsize=12) plt.ylabel('天数', fontsize=12) plt.show()
2025年12月05日
9 阅读
0 评论
0 点赞
2025-12-04
一、matplotlib - 统计图
# 安装依赖 pip install matplotlib1. 折线图import matplotlib.pyplot as plt from matplotlib import rcParams rcParams['font.family'] = 'Microsoft YaHei' # 设置图表大小 plt.figure(figsize=(10, 5)) month = ['一月', '二月', '三月', '四月'] sales = [100, 200, 135, 155] # 绘制折线图 plt.plot(month, sales, label='steam deck', color='orange', linewidth=2, marker='o') # 标题 plt.title('2025年销售数据', fontsize=16) # 坐标轴标签 plt.xlabel('月份') plt.ylabel('销售额(万元)') # 图例 plt.legend(loc='upper left') # 背景 plt.grid(axis='y', alpha=0.3, linestyle='--') # 设置刻度的样式(可选) plt.xticks(rotation=10, fontsize=12) plt.yticks(rotation=0, fontsize=12) # y轴范围 plt.ylim(0, 250) # 在每个坐标点上显示数值 for x, y in zip(month, sales): plt.text(x, y + 5, str(y), ha='center', va='bottom', fontsize=11) plt.show()2. 条形图import matplotlib.pyplot as plt from matplotlib import rcParams rcParams['font.family'] = 'Microsoft YaHei' # 设置图表大小 plt.figure(figsize=(10, 5)) subjects = ['语文', '数学', '英语', '思政'] scores = [93, 96, 60, 90] # bar 纵向柱状图 plt.bar(subjects, scores, label='学生:孙笑川', width=0.3) # 标题 plt.title('期末成绩', fontsize=16) # 坐标轴标签 plt.xlabel('科目') plt.ylabel('分数') # 图例 plt.legend(loc='upper left') # 背景 plt.grid(axis='y', alpha=0.3, linestyle='--') # 设置刻度的样式(可选) plt.xticks(rotation=0, fontsize=12) plt.yticks(rotation=0, fontsize=12) # y轴范围 plt.ylim(0, 100) # 在每个坐标点上显示数值 for x, y in zip(subjects, scores): plt.text(x, y + 5, str(y), ha='center', va='bottom', fontsize=11) # 自动优化排版 plt.tight_layout() plt.show()import matplotlib.pyplot as plt from matplotlib import rcParams rcParams['font.family'] = 'Microsoft YaHei' # 设置图表大小 plt.figure(figsize=(10, 5)) subjects = ['孙笑川', '药水哥', 'Giao哥', '刘波'] scores = [9.3, 9.6, 8.0, 9.0] # barh 横向柱状图 plt.barh(subjects, scores, label='成绩', color='orange') # 标题 plt.title('50米短跑成绩', fontsize=16) # 坐标轴标签 plt.xlabel('用时') plt.ylabel('学生') # 图例 plt.legend(loc='upper right') # 背景 plt.grid(axis='x', alpha=0.3, linestyle='--') # 设置刻度的样式(可选) plt.xticks(rotation=0, fontsize=12) plt.yticks(rotation=0, fontsize=12) # x轴范围 plt.xlim(0, 15) # 在每个坐标点上显示数值 for index, score in enumerate(scores): plt.text(score + 0.5, index, f'{score}', ha='left', va='bottom', fontsize=11) # 自动优化排版 plt.tight_layout() plt.show()3. 饼图import matplotlib.pyplot as plt from matplotlib import rcParams rcParams['font.family'] = 'Microsoft YaHei' # 设置图表大小 plt.figure(figsize=(10, 5)) things = ['看书', '电影', '游泳', '做饭', '其他'] times = [1.5, 2, 1, 2, 0.5] # 配色 colors = ['red', 'skyblue', 'green', 'orange', 'yellow'] # autopct 显示占比 # startangle 初始画图的角度 # colors 饼图配色 # wedgeprops 圆环半径 # pctdistance 百分比显示位置 plt.pie(times, labels=things, autopct='%.1f%%', startangle=90, colors=colors, wedgeprops={'width': 0.6}, pctdistance=0.6) # 标题 plt.title('每日活动时间分布', fontsize=16) plt.text(0, 0, '总计:100%', ha='center', va='bottom', fontsize=10) # 自动优化排版 plt.tight_layout() plt.show()import matplotlib.pyplot as plt from matplotlib import rcParams rcParams['font.family'] = 'Microsoft YaHei' # 设置图表大小 plt.figure(figsize=(10, 5)) things = ['看书', '电影', '游泳', '做饭', '其他'] times = [1.5, 2, 1, 2, 0.5] # 配色 colors = ['red', 'skyblue', 'green', 'orange', 'yellow'] # 爆炸式饼图,设置突出块 explode = (0, 0.2, 0.1, 0, 0.05) # autopct 显示占比 # startangle 初始画图的角度 # colors 饼图配色 # wedgeprops 圆环半径 # pctdistance 百分比显示位置 plt.pie(times, labels=things, autopct='%.1f%%', startangle=90, colors=colors, pctdistance=0.6, explode=explode, shadow=True) # 标题 plt.title('每日活动时间分布', fontsize=16) plt.text(0, 0, '总计:100%', ha='center', va='bottom', fontsize=10) # 自动优化排版 plt.tight_layout() plt.show()4. 散点图import matplotlib.pyplot as plt from matplotlib import rcParams rcParams['font.family'] = 'Microsoft YaHei' # 设置图表大小 plt.figure(figsize=(10, 5)) month = ['一月', '二月', '三月', '四月', '五月', '六月'] sales = [100, 200, 135, 155, 210, 235] # 绘制散点图 plt.scatter(month, sales) # 标题 plt.title('2025年上半年销售趋势', fontsize=16) # 自动优化排版 plt.tight_layout() plt.show()import matplotlib.pyplot as plt from matplotlib import rcParams import random rcParams['font.family'] = 'Microsoft YaHei' # 设置图表大小 plt.figure(figsize=(10, 5)) x = [] y = [] for i in range(500): temp = random.uniform(0, 10) x.append(temp) y.append(2 * temp + random.gauss(0, 2)) # 绘制散点图 plt.scatter(x, y, alpha=0.5, s=20, label='数据') # 标题 plt.title('x、y 变量趋势', fontsize=16) # 坐标轴标签 plt.xlabel('x变量') plt.ylabel('y变量') # 图例 plt.legend(loc='upper left') # 背景 plt.grid(True, alpha=0.3, linestyle='--') # 设置刻度的样式(可选) plt.xticks(rotation=0, fontsize=12) plt.yticks(rotation=0, fontsize=12) # y轴范围 # plt.ylim(0, 30) # 回归线 plt.plot([0, 10], [0, 20], color='red', linewidth=2) # 自动优化排版 plt.tight_layout() plt.show()5. 箱线图import matplotlib.pyplot as plt from matplotlib import rcParams rcParams['font.family'] = 'Microsoft YaHei' # 设置图表大小 plt.figure(figsize=(10, 5)) data = { "语文": [88, 82, 85, 89, 91, 80, 79, 83, 87, 89], "数学": [90, 91, 80, 67, 85, 88, 93, 96, 81, 89], "英语": [96, 88, 83, 45, 89, 73, 77, 80, 98, 66], } # 绘制箱线图 plt.boxplot(data.values(), tick_labels=data.keys()) # 标题 plt.title('各科成绩分布(箱线图)', fontsize=16) # 坐标轴标签 plt.xlabel('科目') plt.ylabel('分数') # 背景 plt.grid(True, alpha=0.3, linestyle='--') # 自动优化排版 plt.tight_layout() plt.show()6. 绘制多个图import matplotlib.pyplot as plt from matplotlib import rcParams rcParams['font.family'] = 'Microsoft YaHei' # 设置图表大小 plt.figure(figsize=(10, 5)) # data month = ['一月', '二月', '三月', '四月'] sales = [100, 200, 135, 155] # subplot 行 列 索引 p1 = plt.subplot(2, 2, 1) p1.plot(month, sales) p2 = plt.subplot(2, 2, 2) p2.bar(month, sales) p2 = plt.subplot(2, 2, 3) p2.scatter(month, sales) p2 = plt.subplot(2, 2, 4) p2.barh(month, sales)
2025年12月04日
10 阅读
0 评论
0 点赞
2025-12-03
七、pandas - 数据分析 - 案例
(1)企鹅体重分析# 1. 导入相关库 import numpy as np import pandas as pd # 2. 导入数据 df = pd.read_csv('static/2_pandas/data/penguins.csv') print(df.head(10)) species island bill_length_mm bill_depth_mm flipper_length_mm \ 0 Adelie Torgersen 39.1 18.7 181.0 1 Adelie Torgersen 39.5 17.4 186.0 2 Adelie Torgersen 40.3 18.0 195.0 3 Adelie Torgersen NaN NaN NaN 4 Adelie Torgersen 36.7 19.3 193.0 5 Adelie Torgersen 39.3 20.6 190.0 6 Adelie Torgersen 38.9 17.8 181.0 7 Adelie Torgersen 39.2 19.6 195.0 8 Adelie Torgersen 34.1 18.1 193.0 9 Adelie Torgersen 42.0 20.2 190.0 body_mass_g sex 0 3750.0 Male 1 3800.0 Female 2 3250.0 Female 3 NaN NaN 4 3450.0 Female 5 3650.0 Male 6 3625.0 Female 7 4675.0 Male 8 3475.0 NaN 9 4250.0 NaN # 3. 数据清洗 # 处理缺失值 df.dropna(inplace=True) # 4. 构造数据特征 df['sex'] = df['sex'].astype('category') df['bill_ratio'] = df['bill_length_mm'] / df['bill_depth_mm'] # print(df.head(10)) # 5. 数据分析 # 数据分箱 - 体重:低、中、高 labels = ['低', '中', '高'] df['mass_level'] = pd.cut(df['body_mass_g'], bins=3, labels=labels) print(df['mass_level'].value_counts()) print() # 按岛屿、性别分组 print(df.groupby(['island', 'sex'], observed=False).agg({ 'body_mass_g': ['mean', 'count'] })) mass_level 低 150 中 128 高 55 Name: count, dtype: int64 body_mass_g mean count island sex Biscoe Female 4319.375000 80 Male 5104.518072 83 Dream Female 3446.311475 61 Male 3987.096774 62 Torgersen Female 3395.833333 24 Male 4034.782609 23(2)睡眠质量分析import numpy as np import pandas as pd # 导入数据 df = pd.read_csv('static/2_pandas/data/sleep.csv') print(df.head(10)) person_id gender age occupation sleep_duration sleep_quality \ 0 1 Male 29 Manual Labor 7.4 7.0 1 2 Female 43 Retired 4.2 4.9 2 3 Male 44 Retired 6.1 6.0 3 4 Male 29 Office Worker 8.3 10.0 4 5 Male 67 Retired 9.1 9.5 5 6 Female 47 Student 6.1 6.9 6 7 Male 22 Office Worker 5.1 6.1 7 8 Male 49 Office Worker 10.7 6.2 8 9 Male 25 Manual Labor 11.9 7.2 9 10 Female 51 Retired 8.2 4.0 physical_activity_level stress_level bmi_category blood_pressure \ 0 41 7 Obese 124/70 1 41 5 Obese 131/86 2 107 4 Underweight 122/70 3 20 10 Obese 124/72 4 19 4 Overweight 133/78 5 24 4 Normal 123/60 6 26 6 Obese 121/70 7 49 8 Obese 134/87 8 27 8 Underweight 112/63 9 64 5 Overweight 125/84 heart_rate daily_steps sleep_disorder 0 91 8539 NaN 1 81 18754 NaN 2 81 2857 NaN 3 55 6886 NaN 4 97 14945 Insomnia 5 87 9485 NaN 6 66 15680 NaN 7 59 18767 NaN 8 99 16397 Sleep Apnea 9 76 12744 NaN # 数据清洗 # 处理缺失值 df.fillna({"sleep_disorder": "unknown"}, inplace=True) # print(df.head(10)) # 构造数据特征 df['gender'] = df['gender'].astype('category') df['occupation'] = df['occupation'].astype('category') df['bmi_category'] = df['bmi_category'].astype('category') df[['high_pressure', 'low_pressure']] = df['blood_pressure'].str.split('/', expand=True) # df.info() # 睡眠质量分箱 labels = ['差', '良', '优'] df['sleep_quality_level'] = pd.cut(df['sleep_quality'], bins=3, labels=labels) print(df.head(3)) person_id gender age occupation sleep_duration sleep_quality \ 0 1 Male 29 Manual Labor 7.4 7.0 1 2 Female 43 Retired 4.2 4.9 2 3 Male 44 Retired 6.1 6.0 physical_activity_level stress_level bmi_category blood_pressure \ 0 41 7 Obese 124/70 1 41 5 Obese 131/86 2 107 4 Underweight 122/70 heart_rate daily_steps sleep_disorder high_pressure low_pressure \ 0 91 8539 unknown 124 70 1 81 18754 unknown 131 86 2 81 2857 unknown 122 70 sleep_quality_level 0 良 1 良 2 良 # 数据分析 print(df['bmi_category'].value_counts()) bmi_category Overweight 109 Underweight 102 Obese 98 Normal 91 Name: count, dtype: int64# 根据bmi分组 bmi_group = df.groupby('bmi_category', observed=True).agg({ 'sleep_duration': 'mean', 'sleep_quality': 'mean', 'stress_level': 'mean' }) print(bmi_group) sleep_duration sleep_quality stress_level bmi_category Normal 7.794505 6.342857 4.857143 Obese 8.072449 6.189796 5.765306 Overweight 8.274312 6.101835 5.642202 Underweight 7.982353 5.896078 5.558824
2025年12月03日
10 阅读
0 评论
0 点赞
2025-12-01
六、pandas - 数据分析
演示数据:data.zip1. 数据的导入导出import pandas as pd # 导入数据 # csv df = pd.read_csv('static/2_pandas/data/employees.csv') print(df.salary.sum()) 691400.0# 导出 df = df.head() df.to_csv('static/2_pandas/data/employees1.csv')# json df_json = pd.read_json('static/2_pandas/data/data1.json') print(df_json) id name age 0 1 张三 25 1 2 李四 30 2 3 王五 28import json # 复杂json with open('static/2_pandas/data/test.json', encoding='utf-8') as f: data = json.load(f) print(type(data)) print(data['users']) print() df_json2 = pd.DataFrame(data['users']) print(df_json2) <class 'dict'> [{'id': 1, 'name': '张三', 'age': 28, 'email': 'zhangsan@example.com', 'is_active': True, 'join_date': '2022-03-15'}, {'id': 2, 'name': '李四', 'age': 35, 'email': 'lisi@example.com', 'is_active': False, 'join_date': '2021-11-02'}, {'id': 3, 'name': '王五', 'age': 24, 'email': 'wangwu@example.com', 'is_active': True, 'join_date': '2023-01-20'}] id name age email is_active join_date 0 1 张三 28 zhangsan@example.com True 2022-03-15 1 2 李四 35 lisi@example.com False 2021-11-02 2 3 王五 24 wangwu@example.com True 2023-01-202. 缺失值的处理import numpy as np import pandas as pd # 缺失值的处理 df = pd.DataFrame([[1, 2, pd.NA], ['A', None, 'D'], [7, 8, 9]], columns=['A', 'B', 'C']) print(df) print() # 检查元素是否是缺失值 print(df.isna()) print(df.isnull()) print() # 计算缺失值个数 # print(df.isna().sum()) # 列 print(df.isna().sum(axis=1)) # 行 A B C 0 1 2.0 <NA> 1 A NaN D 2 7 8.0 9 A B C 0 False False True 1 False True False 2 False False False A B C 0 False False True 1 False True False 2 False False False 0 1 1 1 2 0 dtype: int64# 剔除缺失值 # 剔除包含缺失值的行记录 print(df.dropna()) print() # 当前行的元素都为缺失值时才剔除 print(df.dropna(how='all')) print() # 如果有n个元素不是缺失值,则保留 print(df.dropna(thresh=2)) print() A B C 2 7 8.0 9 A B C 0 1 2.0 <NA> 1 A NaN D 2 7 8.0 9 A B C 0 1 2.0 <NA> 1 A NaN D 2 7 8.0 9# 按列剔除 print(df.dropna(axis=1)) print() # 如果某列有缺失值,则删除这一行 print(df.dropna(subset=['B'])) print() A 0 1 1 A 2 7 A B C 0 1 2.0 <NA> 2 7 8.0 9# 填充缺失值 df = pd.read_csv('static/2_pandas/data/weather_withna.csv') print(df.isna().sum()) date 0 precipitation 303 temp_max 303 temp_min 303 wind 303 weather 303 dtype: int64# 使用字典填充 print(df.fillna({"temp_max": 100, "wind": 20}).tail()) date precipitation temp_max temp_min wind weather 1456 2015-12-27 NaN 100.0 NaN 20.0 NaN 1457 2015-12-28 NaN 100.0 NaN 20.0 NaN 1458 2015-12-29 NaN 100.0 NaN 20.0 NaN 1459 2015-12-30 NaN 100.0 NaN 20.0 NaN 1460 2015-12-31 20.6 12.2 5.0 3.8 rain# 使用统计值填充 print(df.fillna(df[['temp_max', 'wind']].mean()).tail()) date precipitation temp_max temp_min wind weather 1456 2015-12-27 NaN 15.851468 NaN 3.242055 NaN 1457 2015-12-28 NaN 15.851468 NaN 3.242055 NaN 1458 2015-12-29 NaN 15.851468 NaN 3.242055 NaN 1459 2015-12-30 NaN 15.851468 NaN 3.242055 NaN 1460 2015-12-31 20.6 12.200000 5.0 3.800000 rain# 根据附近的值填充 front print(df.ffill().tail()) print() # 根据附近的值填充 behind print(df.bfill().tail()) date precipitation temp_max temp_min wind weather 1456 2015-12-27 0.0 11.1 4.4 4.8 sun 1457 2015-12-28 0.0 11.1 4.4 4.8 sun 1458 2015-12-29 0.0 11.1 4.4 4.8 sun 1459 2015-12-30 0.0 11.1 4.4 4.8 sun 1460 2015-12-31 20.6 12.2 5.0 3.8 rain date precipitation temp_max temp_min wind weather 1456 2015-12-27 20.6 12.2 5.0 3.8 rain 1457 2015-12-28 20.6 12.2 5.0 3.8 rain 1458 2015-12-29 20.6 12.2 5.0 3.8 rain 1459 2015-12-30 20.6 12.2 5.0 3.8 rain 1460 2015-12-31 20.6 12.2 5.0 3.8 rain3. 重复数据处理import pandas as pd data = { "name": ["孙笑川", "药水哥", "孙笑川", "刘波", "冬泳怪鸽", "刘波"], "age": [33, 30, 33, 30, 40, 30], "address": ["成都", "武汉", "成都", "武汉", "北京", "武汉"] } df = pd.DataFrame(data) print(df) name age address 0 孙笑川 33 成都 1 药水哥 30 武汉 2 孙笑川 33 成都 3 刘波 30 武汉 4 冬泳怪鸽 40 北京 5 刘波 30 武汉# 一整条记录都是重复的才标记 print(df.duplicated()) print() # 去重 # print(df.drop_duplicates()) # 根据指定列去重 print(df.drop_duplicates(subset=['address'])) print() # 根据指定列去重(保持最新的记录) print(df.drop_duplicates(subset=['address'], keep='last')) 0 False 1 False 2 True 3 False 4 False 5 True dtype: bool name age address 0 孙笑川 33 成都 1 药水哥 30 武汉 4 冬泳怪鸽 40 北京 name age address 2 孙笑川 33 成都 4 冬泳怪鸽 40 北京 5 刘波 30 武汉4. 数据类型的转换import pandas as pd df = pd.read_csv('static/2_pandas/data/sleep.csv') print(df) person_id gender age occupation sleep_duration sleep_quality \ 0 1 Male 29 Manual Labor 7.4 7.0 1 2 Female 43 Retired 4.2 4.9 2 3 Male 44 Retired 6.1 6.0 3 4 Male 29 Office Worker 8.3 10.0 4 5 Male 67 Retired 9.1 9.5 .. ... ... ... ... ... ... 395 396 Female 36 Student 4.5 7.9 396 397 Female 45 Manual Labor 6.0 6.1 397 398 Female 30 Student 5.3 6.5 398 399 Female 41 Retired 11.0 9.1 399 400 Male 37 Retired 5.8 7.0 physical_activity_level stress_level bmi_category blood_pressure \ 0 41 7 Obese 124/70 1 41 5 Obese 131/86 2 107 4 Underweight 122/70 3 20 10 Obese 124/72 4 19 4 Overweight 133/78 .. ... ... ... ... 395 73 7 Normal 118/66 396 72 8 Obese 132/80 397 58 10 Obese 125/76 398 73 9 Obese 130/75 399 41 6 Normal 118/70 heart_rate daily_steps sleep_disorder 0 91 8539 NaN 1 81 18754 NaN 2 81 2857 NaN 3 55 6886 NaN 4 97 14945 Insomnia .. ... ... ... 395 64 14497 Sleep Apnea 396 65 12848 Insomnia 397 66 15255 Insomnia 398 75 6567 Sleep Apnea 399 51 18079 NaN [400 rows x 13 columns]print(df.dtypes) person_id int64 gender object age int64 occupation object sleep_duration float64 sleep_quality float64 physical_activity_level int64 stress_level int64 bmi_category object blood_pressure object heart_rate int64 daily_steps int64 sleep_disorder object dtype: objectdf.age = df.age.astype('int16') print(df.dtypes) person_id int64 gender object age int16 occupation object sleep_duration float64 sleep_quality float64 physical_activity_level int64 stress_level int64 bmi_category object blood_pressure object heart_rate int64 daily_steps int64 sleep_disorder object dtype: objectdf.gender = df.gender.astype('category') print(df.dtypes) print() print(df.gender) person_id int64 gender category age int16 occupation object sleep_duration float64 sleep_quality float64 physical_activity_level int64 stress_level int64 bmi_category object blood_pressure object heart_rate int64 daily_steps int64 sleep_disorder object dtype: object 0 Male 1 Female 2 Male 3 Male 4 Male ... 395 Female 396 Female 397 Female 398 Female 399 Male Name: gender, Length: 400, dtype: category Categories (2, object): ['Female', 'Male']5. 数据变形import pandas as pd data = { "id": [1001, 1002], "name": ["孙笑川", "刘波"], "math": [99, 89], "english": [60, 95], } df = pd.DataFrame(data) print(df) id name math english 0 1001 孙笑川 99 60 1 1002 刘波 89 95# 行列转置 print(df.T) 0 1 id 1001 1002 name 孙笑川 刘波 math 99 89 english 60 95# 宽表转长表 """ 1001 孙笑川 math 99 1001 孙笑川 english 99 """ print(df) print() df1 = pd.melt(df, id_vars=['id', 'name'], var_name='科目', value_name='分数') print(df1) id name math english 0 1001 孙笑川 99 60 1 1002 刘波 89 95 id name 科目 分数 0 1001 孙笑川 math 99 1 1002 刘波 math 89 2 1001 孙笑川 english 60 3 1002 刘波 english 95# 长表转宽表 df2 = pd.pivot(df1, index=['id', 'name'], columns='科目', values='分数') print(df2) 科目 english math id name 1001 孙笑川 60 99 1002 刘波 95 89# 分列 data = { "id": [1001, 1002], "name": ["孙笑川 带带大师兄", "刘波 药水哥"], "math": [99, 89], "english": [60, 95], } df = pd.DataFrame(data) df[['first name', 'last name']] = df.name.str.split(" ", expand=True) print(df) id name math english first name last name 0 1001 孙笑川 带带大师兄 99 60 孙笑川 带带大师兄 1 1002 刘波 药水哥 89 95 刘波 药水哥df = pd.read_csv('static/2_pandas/data/sleep.csv') df = df[['person_id', 'blood_pressure']] print(df) print() df[['high_pressure', 'low_pressure']] = df['blood_pressure'].str.split("/", expand=True) df.high_pressure = df.high_pressure.astype('int16') df.low_pressure = df.low_pressure.astype('int16') print(df) print() df.info() person_id blood_pressure 0 1 124/70 1 2 131/86 2 3 122/70 3 4 124/72 4 5 133/78 .. ... ... 395 396 118/66 396 397 132/80 397 398 125/76 398 399 130/75 399 400 118/70 [400 rows x 2 columns] person_id blood_pressure high_pressure low_pressure 0 1 124/70 124 70 1 2 131/86 131 86 2 3 122/70 122 70 3 4 124/72 124 72 4 5 133/78 133 78 .. ... ... ... ... 395 396 118/66 118 66 396 397 132/80 132 80 397 398 125/76 125 76 398 399 130/75 130 75 399 400 118/70 118 70 [400 rows x 4 columns] <class 'pandas.core.frame.DataFrame'> RangeIndex: 400 entries, 0 to 399 Data columns (total 4 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 person_id 400 non-null int64 1 blood_pressure 400 non-null object 2 high_pressure 400 non-null int16 3 low_pressure 400 non-null int16 dtypes: int16(2), int64(1), object(1) memory usage: 7.9+ KB6. 数据分箱import pandas as pd df = pd.read_csv('static/2_pandas/data/employees.csv') print(df.head(10)) employee_id first_name last_name email phone_number job_id \ 0 100 Steven King SKING 515.123.4567 AD_PRES 1 101 N_ann Kochhar NKOCHHAR 515.123.4568 AD_VP 2 102 Lex De Haan LDEHAAN 515.123.4569 AD_VP 3 103 Alexander Hunold AHUNOLD 590.423.4567 IT_PROG 4 104 Bruce Ernst BERNST 590.423.4568 IT_PROG 5 105 David Austin DAUSTIN 590.423.4569 IT_PROG 6 106 Valli Pataballa VPATABAL 590.423.4560 IT_PROG 7 107 Diana Lorentz DLORENTZ 590.423.5567 IT_PROG 8 108 Nancy Greenberg NGREENBE 515.124.4569 FI_MGR 9 109 Daniel Faviet DFAVIET 515.124.4169 FI_ACCOUNT salary commission_pct manager_id department_id 0 24000.0 NaN NaN 90.0 1 17000.0 NaN 100.0 90.0 2 17000.0 NaN 100.0 90.0 3 9000.0 NaN 102.0 60.0 4 6000.0 NaN 103.0 60.0 5 4800.0 NaN 103.0 60.0 6 4800.0 NaN 103.0 60.0 7 4200.0 NaN 103.0 60.0 8 12000.0 NaN 101.0 100.0 9 9000.0 NaN 108.0 100.0 df1 = df.head(10)[['employee_id', 'salary']] print(df1) print() # pd.cut() # bins=n 分成n段区间,起始值,结束值是所有数据中的最小值、最大值 print(pd.cut(df1['salary'], bins=2)) print() # bins=[] 自定义区间的值 df1_cut = pd.cut(df1['salary'], bins=[0, 5000, 10000, 20000]) print(df1_cut) print() df1_cut['收入范围'] = pd.cut(df1['salary'], bins=[0, 5000, 10000, 20000], labels=['低', '中', '高']) print(df1_cut) print() # 等分为指定的段数 df1_qcut = pd.qcut(df1['salary'], 3) print(df1_qcut) employee_id salary 0 100 24000.0 1 101 17000.0 2 102 17000.0 3 103 9000.0 4 104 6000.0 5 105 4800.0 6 106 4800.0 7 107 4200.0 8 108 12000.0 9 109 9000.0 0 (14100.0, 24000.0] 1 (14100.0, 24000.0] 2 (14100.0, 24000.0] 3 (4180.2, 14100.0] 4 (4180.2, 14100.0] 5 (4180.2, 14100.0] 6 (4180.2, 14100.0] 7 (4180.2, 14100.0] 8 (4180.2, 14100.0] 9 (4180.2, 14100.0] Name: salary, dtype: category Categories (2, interval[float64, right]): [(4180.2, 14100.0] < (14100.0, 24000.0]] 0 NaN 1 (10000.0, 20000.0] 2 (10000.0, 20000.0] 3 (5000.0, 10000.0] 4 (5000.0, 10000.0] 5 (0.0, 5000.0] 6 (0.0, 5000.0] 7 (0.0, 5000.0] 8 (10000.0, 20000.0] 9 (5000.0, 10000.0] Name: salary, dtype: category Categories (3, interval[int64, right]): [(0, 5000] < (5000, 10000] < (10000, 20000]] 0 NaN 1 (10000, 20000] 2 (10000, 20000] 3 (5000, 10000] 4 (5000, 10000] 5 (0, 5000] 6 (0, 5000] 7 (0, 5000] 8 (10000, 20000] 9 (5000, 10000] 收入范围 0 NaN 1 高 2 高 3 中 4 中 5... Name: salary, dtype: object 0 (12000.0, 24000.0] 1 (12000.0, 24000.0] 2 (12000.0, 24000.0] 3 (6000.0, 12000.0] 4 (6000.0, 12000.0] 5 (4199.999, 6000.0] 6 (4199.999, 6000.0] 7 (4199.999, 6000.0] 8 (12000.0, 24000.0] 9 (6000.0, 12000.0] Name: salary, dtype: category Categories (3, interval[float64, right]): [(4199.999, 6000.0] < (6000.0, 12000.0] < (12000.0, 24000.0]]df = pd.read_csv('static/2_pandas/data/sleep.csv') df1 = df.head(10)[['person_id', 'sleep_quality']] # 源数据 ---> 分箱 ---> 统计 df1['睡眠质量'] = pd.cut(df1['sleep_quality'], bins=3, labels=['差', '良好', '优秀']) print(df1['睡眠质量'].value_counts()) 睡眠质量 良好 5 差 3 优秀 2 Name: count, dtype: int64# df.rename() df = pd.DataFrame({ "name": ["孙笑川", "药水哥", "刘波", "冬泳怪鸽"], "age": [33, 30, 40, 30], "address": ["成都", "武汉", "武汉", "北京"] }) print(df) print() print(df.rename(index={0: 5}, columns={"address": "地址"})) name age address 0 孙笑川 33 成都 1 药水哥 30 武汉 2 刘波 40 武汉 3 冬泳怪鸽 30 北京 name age 地址 5 孙笑川 33 成都 1 药水哥 30 武汉 2 刘波 40 武汉 3 冬泳怪鸽 30 北京# df.set_index() # inplace=True 在原数据上修改 df.set_index('name', inplace=True) print(df) age address name 孙笑川 33 成都 药水哥 30 武汉 刘波 40 武汉 冬泳怪鸽 30 北京# df.reset_index() df.reset_index(inplace=True) print(df) name age address 0 孙笑川 33 成都 1 药水哥 30 武汉 2 刘波 40 武汉 3 冬泳怪鸽 30 北京7. 时间数据的处理import pandas as pd d = pd.Timestamp('2025-12-03 14:58') print(d) print(type(d)) 2025-12-03 14:58:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'># 属性 print("年:", d.year) print("月:", d.month) print("日:", d.day) print("时间:", d.hour, d.minute, d.second) print("是否为当月的最后一天:", d.is_month_end) 年: 2025 月: 12 日: 3 时间: 14 58 0 是否为当月的最后一天: False# 方法 print("周几:", d.day_name()) print("转换为日期(天):", d.to_period('D')) 周几: Wednesday 转换为日期(天): 2025-12-03# 字符串转换为日期类型 d = pd.to_datetime('2025-12-03 14:58') print(d) print(type(d)) 2025-12-03 14:58:00 <class 'pandas._libs.tslibs.timestamps.Timestamp'>df = pd.DataFrame({ "id": [1001, 1002], "name": ["孙笑川", "药水哥"], "date_str": ["20251201", "20251202"] }) print(df) print() df['create_time'] = pd.to_datetime(df['date_str']) print(df) print() df['week'] = df['create_time'].dt.day_name() print(df) id name date_str 0 1001 孙笑川 20251201 1 1002 药水哥 20251202 id name date_str create_time 0 1001 孙笑川 20251201 2025-12-01 1 1002 药水哥 20251202 2025-12-02 id name date_str create_time week 0 1001 孙笑川 20251201 2025-12-01 Monday 1 1002 药水哥 20251202 2025-12-02 Tuesday# csv中的日期转换 df = pd.read_csv('static/2_pandas/data/weather.csv') df['datetime'] = pd.to_datetime(df['date']) print(df.head(10)) print() # 读取csv时同步进行转换 df = pd.read_csv('static/2_pandas/data/weather.csv', parse_dates=['date']) print(df['date'].dtypes) date precipitation temp_max temp_min wind weather datetime 0 2012-01-01 0.0 12.8 5.0 4.7 drizzle 2012-01-01 1 2012-01-02 10.9 10.6 2.8 4.5 rain 2012-01-02 2 2012-01-03 0.8 11.7 7.2 2.3 rain 2012-01-03 3 2012-01-04 20.3 12.2 5.6 4.7 rain 2012-01-04 4 2012-01-05 1.3 8.9 2.8 6.1 rain 2012-01-05 5 2012-01-06 2.5 4.4 2.2 2.2 rain 2012-01-06 6 2012-01-07 0.0 7.2 2.8 2.3 rain 2012-01-07 7 2012-01-08 0.0 10.0 2.8 2.0 sun 2012-01-08 8 2012-01-09 4.3 9.4 5.0 3.4 rain 2012-01-09 9 2012-01-10 1.0 6.1 0.6 3.4 rain 2012-01-10 datetime64[ns]# 日期数据作为索引 df1 = df.set_index('date') print(df1) print() precipitation temp_max temp_min wind weather date 2012-01-01 0.0 12.8 5.0 4.7 drizzle 2012-01-02 10.9 10.6 2.8 4.5 rain 2012-01-03 0.8 11.7 7.2 2.3 rain 2012-01-04 20.3 12.2 5.6 4.7 rain 2012-01-05 1.3 8.9 2.8 6.1 rain ... ... ... ... ... ... 2015-12-27 8.6 4.4 1.7 2.9 rain 2015-12-28 1.5 5.0 1.7 1.3 rain 2015-12-29 0.0 7.2 0.6 2.6 fog 2015-12-30 0.0 5.6 -1.0 3.4 sun 2015-12-31 0.0 5.6 -2.1 3.5 sun [1461 rows x 5 columns]# 时间间隔 d1 = pd.Timestamp('2020-01-10') d2 = pd.Timestamp('2020-03-05') print(d2-d1) 55 days 00:00:00# 按时间维度重采样 df = pd.read_csv('static/2_pandas/data/weather.csv', parse_dates=['date']) df.set_index('date', inplace=True) print(df[['temp_max', 'temp_min']].resample("YE").mean()) temp_max temp_min date 2012-12-31 15.276776 7.289617 2013-12-31 16.058904 8.153973 2014-12-31 16.995890 8.662466 2015-12-31 17.427945 8.8356168. 分组聚合# df.groupby('分组的字段')['聚合的字段'].聚合函数 import pandas as pd df = pd.read_csv('static/2_pandas/data/employees.csv') print(df.head(10)) employee_id first_name last_name email phone_number job_id \ 0 100 Steven King SKING 515.123.4567 AD_PRES 1 101 N_ann Kochhar NKOCHHAR 515.123.4568 AD_VP 2 102 Lex De Haan LDEHAAN 515.123.4569 AD_VP 3 103 Alexander Hunold AHUNOLD 590.423.4567 IT_PROG 4 104 Bruce Ernst BERNST 590.423.4568 IT_PROG 5 105 David Austin DAUSTIN 590.423.4569 IT_PROG 6 106 Valli Pataballa VPATABAL 590.423.4560 IT_PROG 7 107 Diana Lorentz DLORENTZ 590.423.5567 IT_PROG 8 108 Nancy Greenberg NGREENBE 515.124.4569 FI_MGR 9 109 Daniel Faviet DFAVIET 515.124.4169 FI_ACCOUNT salary commission_pct manager_id department_id 0 24000.0 NaN NaN 90.0 1 17000.0 NaN 100.0 90.0 2 17000.0 NaN 100.0 90.0 3 9000.0 NaN 102.0 60.0 4 6000.0 NaN 103.0 60.0 5 4800.0 NaN 103.0 60.0 6 4800.0 NaN 103.0 60.0 7 4200.0 NaN 103.0 60.0 8 12000.0 NaN 101.0 100.0 9 9000.0 NaN 108.0 100.0 # 缺失值处理 df = df.dropna(subset=['department_id']) df['department_id'] = df['department_id'].astype('int64') print(df.head(10)) employee_id first_name last_name email phone_number job_id \ 0 100 Steven King SKING 515.123.4567 AD_PRES 1 101 N_ann Kochhar NKOCHHAR 515.123.4568 AD_VP 2 102 Lex De Haan LDEHAAN 515.123.4569 AD_VP 3 103 Alexander Hunold AHUNOLD 590.423.4567 IT_PROG 4 104 Bruce Ernst BERNST 590.423.4568 IT_PROG 5 105 David Austin DAUSTIN 590.423.4569 IT_PROG 6 106 Valli Pataballa VPATABAL 590.423.4560 IT_PROG 7 107 Diana Lorentz DLORENTZ 590.423.5567 IT_PROG 8 108 Nancy Greenberg NGREENBE 515.124.4569 FI_MGR 9 109 Daniel Faviet DFAVIET 515.124.4169 FI_ACCOUNT salary commission_pct manager_id department_id 0 24000.0 NaN NaN 90 1 17000.0 NaN 100.0 90 2 17000.0 NaN 100.0 90 3 9000.0 NaN 102.0 60 4 6000.0 NaN 103.0 60 5 4800.0 NaN 103.0 60 6 4800.0 NaN 103.0 60 7 4200.0 NaN 103.0 60 8 12000.0 NaN 101.0 100 9 9000.0 NaN 108.0 100 # 计算不同部门的平均薪资 # .groups 查看分组 print(df.groupby('department_id').groups) print() # get_group() 查看具体的分组数据 print(df.groupby('department_id').get_group(20)) {10: [100], 20: [101, 102], 30: [14, 15, 16, 17, 18, 19], 40: [103], 50: [20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99], 60: [3, 4, 5, 6, 7], 70: [104], 80: [45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 79], 90: [0, 1, 2], 100: [8, 9, 10, 11, 12, 13], 110: [105, 106]} employee_id first_name last_name email phone_number job_id \ 101 201 Michael Hartstein MHARTSTE 515.123.5555 MK_MAN 102 202 Pat Fay PFAY 603.123.6666 MK_REP salary commission_pct manager_id department_id 101 13000.0 NaN 100.0 20 102 6000.0 NaN 201.0 20 df1 = df.groupby('department_id')[['salary']].mean() df1['salary'] = df1['salary'].round(2) df1.reset_index(inplace=True) print(df1.sort_values('salary', ascending=False)) department_id salary 8 90 19333.33 10 110 10150.00 6 70 10000.00 1 20 9500.00 7 80 8955.88 9 100 8600.00 3 40 6500.00 5 60 5760.00 0 10 4400.00 2 30 4150.00 4 50 3475.56# 按部门、岗位分组聚合 df2 = df.groupby(['department_id', 'job_id'])[['salary']].mean() df2['salary'] = df2['salary'].round(2) df2.reset_index(inplace=True) print(df2.sort_values('salary', ascending=False)) department_id job_id salary 13 90 AD_PRES 24000.00 14 90 AD_VP 17000.00 1 20 MK_MAN 13000.00 11 80 SA_MAN 12200.00 16 100 FI_MGR 12000.00 18 110 AC_MGR 12000.00 4 30 PU_MAN 11000.00 10 70 PR_REP 10000.00 12 80 SA_REP 8396.55 17 110 AC_ACCOUNT 8300.00 15 100 FI_ACCOUNT 7920.00 8 50 ST_MAN 7280.00 5 40 HR_REP 6500.00 2 20 MK_REP 6000.00 9 60 IT_PROG 5760.00 0 10 AD_ASST 4400.00 6 50 SH_CLERK 3215.00 7 50 ST_CLERK 2785.00 3 30 PU_CLERK 2780.00
2025年12月01日
27 阅读
0 评论
0 点赞
2025-11-28
五、pandas-DataFrame-案例
(1)学生成绩分析某班级的学生成绩如下:姓名语文数学英语孙笑川909565药水哥919670Giao哥808990刘波7588951.计算每名学生的总分和平均分2.找出数学成绩高于90分或英语成绩高于85分的学生3.按总分降序排序(显示前三名)import numpy as np import pandas as pd data = { "姓名": ["孙笑川", "药水哥", "Giao哥", "刘波"], "语文": [90, 91, 80, 75], "数学": [95, 96, 89, 88], "英语": [65, 70, 90, 95] } scores = pd.DataFrame(data) print(scores) 姓名 语文 数学 英语 0 孙笑川 90 95 65 1 药水哥 91 96 70 2 Giao哥 80 89 90 3 刘波 75 88 95scores['总分'] = scores[['语文', '数学', '英语']].sum(axis=1) print(scores) print("================================================") # scores['平均分'] = scores['总分'] / 3 scores['平均分'] = scores[['语文', '数学', '英语']].mean(axis=1) print(scores) 姓名 语文 数学 英语 总分 0 孙笑川 90 95 65 250 1 药水哥 91 96 70 257 2 Giao哥 80 89 90 259 3 刘波 75 88 95 258 ================================================ 姓名 语文 数学 英语 总分 平均分 0 孙笑川 90 95 65 250 83.333333 1 药水哥 91 96 70 257 85.666667 2 Giao哥 80 89 90 259 86.333333 3 刘波 75 88 95 258 86.000000print(scores[(scores['数学'] > 90) | (scores['英语'] > 85)]) 姓名 语文 数学 英语 总分 平均分 0 孙笑川 90 95 65 250 83.333333 1 药水哥 91 96 70 257 85.666667 2 Giao哥 80 89 90 259 86.333333 3 刘波 75 88 95 258 86.000000# print(scores.sort_values('总分', ascending=False).head(3)) print(scores.nlargest(3, columns='总分')) 姓名 语文 数学 英语 总分 平均分 2 Giao哥 80 89 90 259 86.333333 3 刘波 75 88 95 258 86.000000 1 药水哥 91 96 70 257 85.666667(2)销售数据分析某公司销售数据如下:产品名称苹果西瓜葡萄梨单价(斤/元)8.53.5105.5销量(斤)5010020300计算每种产品的总销售额2.找出销售额最高的商品3.按销售额降序排序import numpy as np import pandas as pd data = { "产品名称": ["苹果", "西瓜", "葡萄", "梨"], "单价(斤/元)": [8.5, 3.5, 10, 5.5], "销量(斤)": [50, 100, 20, 300] } df = pd.DataFrame(data) print(df) 产品名称 单价(斤/元) 销量(斤) 0 苹果 8.5 50 1 西瓜 3.5 100 2 葡萄 10.0 20 3 梨 5.5 300df['总销售额'] = df['单价(斤/元)'] * df['销量(斤)'] print(df) 产品名称 单价(斤/元) 销量(斤) 总销售额 0 苹果 8.5 50 425.0 1 西瓜 3.5 100 350.0 2 葡萄 10.0 20 200.0 3 梨 5.5 300 1650.0print(df.nlargest(1, columns='总销售额')) 产品名称 单价(斤/元) 销量(斤) 总销售额 3 梨 5.5 300 1650.0print(df.sort_values('总销售额', ascending=False)) 产品名称 单价(斤/元) 销量(斤) 总销售额 3 梨 5.5 300 1650.0 0 苹果 8.5 50 425.0 1 西瓜 3.5 100 350.0 2 葡萄 10.0 20 200.0(3)电商用户行为分析某电商平台的用户行为数据如下:用户ID用户名商品类别商品单价购买数量1孙笑川电子产品300052药水哥服装200103Giao哥电子产品500054刘波日用50020 冬泳怪鸽五金30151.计算每位用户的总消费金额2.找出消费金额最高的用户3.计算用户的平均消费金额(保留两位小数)4.统计电子产品的总购买数量import numpy as np import pandas as pd data = { "用户ID": [1, 2, 3, 4, 5], "用户名": ["孙笑川", "药水哥", "Giao哥", "刘波", "冬泳怪鸽"], "商品类别": ["电子产品", "服装", "电子产品", "日用", "五金"], "商品单价": [3000, 200, 5000, 500, 30], "购买数量": [5, 10, 5, 20, 15], } df = pd.DataFrame(data) print(df) 用户ID 用户名 商品类别 商品单价 购买数量 0 1 孙笑川 电子产品 3000 5 1 2 药水哥 服装 200 10 2 3 Giao哥 电子产品 5000 5 3 4 刘波 日用 500 20 4 5 冬泳怪鸽 五金 30 15df['总消费金额'] = df['商品单价'] * df['购买数量'] print(df) 用户ID 用户名 商品类别 商品单价 购买数量 总消费金额 0 1 孙笑川 电子产品 3000 5 15000 1 2 药水哥 服装 200 10 2000 2 3 Giao哥 电子产品 5000 5 25000 3 4 刘波 日用 500 20 10000 4 5 冬泳怪鸽 五金 30 15 450print(df.nlargest(1, columns='总消费金额')) 用户ID 用户名 商品类别 商品单价 购买数量 总消费金额 2 3 Giao哥 电子产品 5000 5 25000cost = df['总消费金额'].mean() print(cost) 10490.0print(df[df['商品类别'] == '电子产品']['购买数量'].sum()) 10
2025年11月28日
11 阅读
0 评论
0 点赞
2025-11-24
四、pandas - DataFrame
1. 创建方法import numpy as np import pandas as pd # 通过Series创建 s1 = pd.Series([1, 2, 3]) s2 = pd.Series([4, 5, 6]) df = pd.DataFrame({"1": s1, "2": s2}) print(df) 1 2 0 1 4 1 2 5 2 3 6# 通过字典创建 # 可以通过columns属性指定列的顺序 df = pd.DataFrame( { "id": [1, 2, 3], "name": ["孙笑川", "药水哥", "Giao哥"], "age": [33, 30, 33] } ) print(df) id name age 0 1 孙笑川 33 1 2 药水哥 30 2 3 Giao哥 332. 属性属性说明index行索引values值dtypes元素类型shape形状ndim维度size元素个数columns列标签loc[]显示索引,按行列标签索引或切片iloc[]隐式索引,按行列位置索引或切片at[]使用行列标签访问指定元素iat[]使用行列位置访问指定元素T行列转置print("行索引:", df.index) print("列标签", df.columns) print("值:", df.values) 行索引: RangeIndex(start=0, stop=3, step=1) 列标签 Index(['id', 'name', 'age'], dtype='object') 值: [[1 '孙笑川' 33] [2 '药水哥' 30] [3 'Giao哥' 33]]print("形状:", df.shape) print("维度:", df.ndim) print("数据类型:") print(df.dtypes) 形状: (3, 3) 维度: 2 数据类型: id int64 name object age int64 dtype: object# 行数据 # loc print(df.loc[1]) print("==================") # iloc print(df.iloc[1]) id 2 name 药水哥 age 30 Name: 1, dtype: object ================== id 2 name 药水哥 age 30 Name: 1, dtype: object# 列数据 print(df.loc[:, 'name']) print("==================") print(df.iloc[:, 1]) 0 孙笑川 1 药水哥 2 Giao哥 Name: name, dtype: object ================== 0 孙笑川 1 药水哥 2 Giao哥 Name: name, dtype: object# 获取指定元素 print(df.at[0, 'name']) print("==================") print(df.iat[0, 1]) print("==================") print(df.loc[0, 'name']) print("==================") print(df.iloc[0, 1]) 孙笑川 ================== 孙笑川 ================== 孙笑川 ================== 孙笑川# 行列转置 #print(df.T)# 获取单列数据 print(df['name']) print("==================") print(df.name) print("==================") column = df[['name']] print(column) print(type(column)) 0 孙笑川 1 药水哥 2 Giao哥 Name: name, dtype: object ================== 0 孙笑川 1 药水哥 2 Giao哥 Name: name, dtype: object ================== name 0 孙笑川 1 药水哥 2 Giao哥 <class 'pandas.core.frame.DataFrame'># 多列数据 print(df[['name', 'age']]) name age 0 孙笑川 33 1 药水哥 30 2 Giao哥 33# 获取部分数据 print(df.head(2)) print("==================") print(df.tail(2)) id name age 0 1 孙笑川 33 1 2 药水哥 30 ================== id name age 1 2 药水哥 30 2 3 Giao哥 33# 布尔索引 print(df[df.age > 32]) print("==================") print(df[(df.age > 32) & (df.id == 1)]) id name age 0 1 孙笑川 33 2 3 Giao哥 33 ================== id name age 0 1 孙笑川 33# 随机抽样 print(df.sample(2)) id name age 0 1 孙笑川 33 2 3 Giao哥 333. 常用方法方法说明head()获取前n行数据,默认值5tail()获取后n行数据,默认值5isin()判断元素是否包含在参数集合中isna()判断每一个元素是否为缺失值(NaN/None)sum()求和,自动忽略缺失值mean()平均值min()最小值max()最大值var()方差std()标准差median()中位数mode()众数(可以有多个返回值)quantile(q)分位数,q取值范围为:0~1describe()常见统计信息(count、mean、std、min、25%、50%、75%、max)value_counts()每个唯一值的出现次数count()非缺失值数量duplicated()是否重复drop_duplicates()去除重复项sample()随机抽样replace()替换sort_index()按索引排序sort_values()按值排序nlargest()返回某列最大的n条数据nsmallest()返回某列最小的n条数据df = pd.DataFrame( { "id": [1, 2, 3], "name": ["孙笑川", "药水哥", "Giao哥"], "age": [33, 30, 31], "address": ["成都", "武汉", "河南"] } ) print(df) id name age address 0 1 孙笑川 33 成都 1 2 药水哥 30 武汉 2 3 Giao哥 31 河南print(df.head(1)) print("============================") print(df.tail(1)) id name age address 0 1 孙笑川 33 成都 ============================ id name age address 2 3 Giao哥 31 河南# 查看元素是否包含在参数集合中 print(df.isin(["药水哥", 31])) id name age address 0 False False False False 1 False True False False 2 False False True False# 查看元素是否是缺失值 print(df.isna()) id name age address 0 False False False False 1 False False False False 2 False False False False# 求和 print(df.sum()) print("============================") print(df.age.sum()) id 6 name 孙笑川药水哥Giao哥 age 94 address 成都武汉河南 dtype: object ============================ 94# 最值 print(df.age.max()) print(df.name.min()) 33 Giao哥# 平均数 print(df.age.mean()) # 中位数 print(df.age.median()) # 众数 print(df.age.mode()) 31.333333333333332 31.0 0 30 1 31 2 33 Name: age, dtype: int64# 标准差 print(df.age.std()) # 方差 print(df.age.var()) # 分位数 print(df.age.quantile(0.25)) 1.5275252316519468 2.3333333333333335 30.5# 描述信息 print(df.describe()) id age count 3.0 3.000000 mean 2.0 31.333333 std 1.0 1.527525 min 1.0 30.000000 25% 1.5 30.500000 50% 2.0 31.000000 75% 2.5 32.000000 max 3.0 33.000000# 每一列中非缺失值的个数 print(df.count()) id 3 name 3 age 3 address 3 dtype: int64# 每一个唯一值的出现次数 print(df.value_counts()) id name age address 1 孙笑川 33 成都 1 2 药水哥 30 武汉 1 3 Giao哥 31 河南 1 Name: count, dtype: int64# 去重 print(df.drop_duplicates()) id name age address 0 1 孙笑川 33 成都 1 2 药水哥 30 武汉 2 3 Giao哥 31 河南# 判重 print(df.duplicated()) print("============================") # 指定列判重 print(df.duplicated(subset="name")) 0 False 1 False 2 False dtype: bool ============================ 0 False 1 False 2 False dtype: bool# 随机抽样 print(df.sample()) id name age address 2 3 Giao哥 31 河南# replace print(df.replace(30, 35)) id name age address 0 1 孙笑川 33 成都 1 2 药水哥 35 武汉 2 3 Giao哥 31 河南# 累计和 print(df.cumsum()) print("============================") # 参数 axis 0:按列累计,1按行累计 # 注:累计时需确保元素类型一直 print(df.cummax(axis=0)) id name age address 0 1 孙笑川 33 成都 1 3 孙笑川药水哥 63 成都武汉 2 6 孙笑川药水哥Giao哥 94 成都武汉河南 ============================ id name age address 0 1 孙笑川 33 成都 1 2 药水哥 33 武汉 2 3 药水哥 33 河南# 排序 print(df.sort_index()) print("============================") # 按值排序时需指定按哪一列排 print(df.sort_values(by='name')) print("============================") # 多列排序,并指定排序方式 False:倒序 True:升序 print(df.sort_values(by=['name', 'age'], ascending=[False, False])) id name age address 0 1 孙笑川 33 成都 1 2 药水哥 30 武汉 2 3 Giao哥 31 河南 ============================ id name age address 2 3 Giao哥 31 河南 0 1 孙笑川 33 成都 1 2 药水哥 30 武汉 ============================ id name age address 1 2 药水哥 30 武汉 0 1 孙笑川 33 成都 2 3 Giao哥 31 河南print(df.nlargest(2, columns=['age'])) print("============================") print(df.nsmallest(2, columns=['age'])) id name age address 0 1 孙笑川 33 成都 2 3 Giao哥 31 河南 ============================ id name age address 1 2 药水哥 30 武汉 2 3 Giao哥 31 河南
2025年11月24日
9 阅读
0 评论
0 点赞
1
2
...
6