好的,这是对您提供的关于 Pandas 的文章进行格式化、修正和优化的 Markdown 版本。
我已完成以下工作:
转换为 Markdown 格式:使用了标题、列表、表格和代码块,使其更具可读性。
删除错误和Traceback:移除了代码执行的完整错误堆栈,并修正了导致错误的代码。
优化代码和注释:
将效率低下的
for
循环数据清洗代码替换为 Pandas 推荐的向量化操作。修正了方法调用中的小错误(如
value_counts
忘记加()
)。补充了注释,解释了错误原因和推荐做法。
调整结构和语言:使文章的逻辑更清晰,语言更流畅。
Pandas 入门教程
参考资料
xxxxxxxxxx
import pandas as pd
import numpy as np
Pandas 主要用于处理表格类型的数据,它提供了强大的数据结构和分析工具。
Pandas 读取数据
Pandas 可以从多种数据源读取数据并转换为 DataFrame 对象。
数据类型 | 说明 | 读取函数 |
---|---|---|
csv, tsv, txt | 逗号/Tab分隔的纯文本文件 | pd.read_csv() |
excel | 微软 xls 或 xlsx 文件 | pd.read_excel() |
mysql | 关系型数据库 | pd.read_sql() |
读取纯文本文件 (CSV, TXT)
xxxxxxxxxx
# 读取 .csv 文件,文件第一行默认为表头
df_csv = pd.read_csv('data/stat.csv')
print(df_csv)
# 读取 .txt 文件,如果文件没有表头,需要使用 names 参数指定列名
df_txt = pd.read_csv('data/stat.txt', names=['character name', 'age', 'first appear'])
print(df_txt)
输出:
xxxxxxxxxx
name age appear
0 hakurei reimu 28 th1
1 kirisame marisa 27 th2
2 cirno 24 th6
character name age first appear
0 hakurei reimu 28 th1
1 kirisame marisa 27 th2
2 cirno 24 th6
读取 Excel 文件
xxxxxxxxxx
df_excel = pd.read_excel('data/stat.xlsx')
print(df_excel)
输出:
xxxxxxxxxx
姓名 年龄 首次出场
0 博丽灵梦 28 th1
1 雾雨魔理沙 27 th2
2 琪露诺 24 th6
从 MySQL 数据库读取
新版本的 Pandas 推荐使用 SQLAlchemy
来创建数据库连接,以保证最佳的兼容性。直接使用 pymysql
等库的连接对象可能会出现以下警告:
UserWarning: pandas only supports SQLAlchemy connectable (engine/connection) or database string URI or sqlite3 DBAPI2 connection. Other DBAPI2 objects are not tested. Please consider using SQLAlchemy.
推荐做法如下:
xxxxxxxxxx
from sqlalchemy import create_engine
import pandas as pd
# 1. 配置数据库连接信息
MYSQL_HOST = 'localhost'
MYSQL_PORT = '3306'
MYSQL_USER = 'root'
MYSQL_PASSWORD = '123456' # 请替换为你的密码
MYSQL_DB = 'pandasstat'
CHARSET = 'utf8'
# 2. 创建 SQLAlchemy 引擎
engine = create_engine(
f'mysql+pymysql://{MYSQL_USER}:{MYSQL_PASSWORD}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DB}?charset={CHARSET}'
)
# 3. 编写 SQL 查询语句并读取数据
sql_query = "SELECT * FROM stat"
df_sql = pd.read_sql(sql_query, con=engine)
print(df_sql)
输出:
xxxxxxxxxx
name age appear
0 reimu 28 th1
1 marisa 27 th2
2 cirno 24 th6
Pandas 数据结构
Series (一维数据)
Series
是一种类似于一维数组的对象,它由一组数据和一组相关的数据标签(即索引)组成。可以看作是带标签的一维数组。
xxxxxxxxxx
# 从列表创建 Series,索引默认为 0, 1, 2...
s1 = pd.Series(["reimu", 28, "th1"])
print(s1)
# 获取索引和数据
print("\nIndex:", s1.index)
print("Values:", s1.values)
输出:
xxxxxxxxxx
0 reimu
1 28
2 th1
dtype: object
Index: RangeIndex(start=0, stop=3, step=1)
Values: ['reimu' 28 'th1']
xxxxxxxxxx
# 从字典创建 Series,字典的键成为索引
s2 = pd.Series({"name": "reimu", "age": 28})
print(s2)
# 使用索引标签进行查询
print("\nName:", s2["name"])
print("\nMultiple items:\n", s2[["name", "age"]])
输出:
xxxxxxxxxx
name reimu
age 28
dtype: object
Name: reimu
Multiple items:
name reimu
age 28
dtype: object
DataFrame (二维数据)
DataFrame
是一个表格型的数据结构,可以看作是由多个 Series
组成的字典。
每列可以是不同的值类型(数值、字符串、布尔值等)。
同时拥有行索引(index)和列索引(columns)。
xxxxxxxxxx
# 从字典创建 DataFrame
df = pd.DataFrame({
"name": ["reimu", 'marisa'],
"age": [28, 27],
"appear": ["th1", "th2"]
})
print(df)
print("\nData types:\n", df.dtypes)
print("\nColumns:", df.columns)
print("Index:", df.index)
输出:
xxxxxxxxxx
name age appear
0 reimu 28 th1
1 marisa 27 th2
Data types:
name object
age int64
appear object
dtype: object
Columns: Index(['name', 'age', 'appear'], dtype='object')
Index: RangeIndex(start=0, stop=2, step=1)
从 DataFrame 中查询 Series
查询单行或单列,返回的是
pd.Series
。查询多行或多列,返回的是
pd.DataFrame
。
xxxxxxxxxx
# 查询一列,返回 Series
name_series = df["name"]
print(type(name_series))
print(name_series)
输出:
xxxxxxxxxx
<class 'pandas.core.series.Series'>
0 reimu
1 marisa
Name: name, dtype: object
xxxxxxxxxx
# 查询多列,返回 DataFrame
sub_df = df[["name", "age"]]
print(type(sub_df))
print(sub_df)
输出:
xxxxxxxxxx
<class 'pandas.core.frame.DataFrame'>
name age
0 reimu 28
1 marisa 27
xxxxxxxxxx
# 使用 .loc 按行标签查询,返回 Series
row_series = df.loc[1]
print(type(row_series))
print(row_series)
输出:
xxxxxxxxxx
<class 'pandas.core.series.Series'>
name marisa
age 27
appear th2
Name: 1, dtype: object
xxxxxxxxxx
# .loc 进行切片查询,注意:.loc 的切片是左右都包含的
rows_df = df.loc[0:1]
print(type(rows_df))
print(rows_df)
输出:
xxxxxxxxxx
<class 'pandas.core.frame.DataFrame'>
name age appear
0 reimu 28 th1
1 marisa 27 th2
Pandas 数据查询
Pandas 提供了多种强大的查询方式,其中 .loc
和 .iloc
最为常用。
df.loc
: 根据行、列的标签值进行查询。df.iloc
: 根据行、列的数字位置进行查询。df.where
: 根据条件进行筛选,不满足条件的位置用NaN
填充。df.query
: 使用字符串表达式进行查询。
使用 df.loc
查询数据(推荐)
.loc
非常灵活,支持多种查询方式,并且可以用于数据赋值。
准备数据: 首先,我们加载天气数据并进行一些预处理。
xxxxxxxxxx
# 加载数据
df = pd.read_excel("天气数据.xlsx")
# --- 数据清洗 ---
# 1. 清理“日期”列,移除星期信息 (使用向量化操作,比 for 循环更高效)
df["日期"] = df["日期"].str.replace(r"\s周.*$", "", regex=True)
# 2. 清理温度列,移除'°'并转换为整数
df["最高温"] = df["最高温"].str.replace("°", "").astype(int)
df["最低温"] = df["最低温"].str.replace("°", "").astype(int)
# 3. 将“日期”列设为索引
df.set_index("日期", inplace=True)
df.head()
输出:
日期 | 最高温 | 最低温 | 天气 | 风力风向 |
---|---|---|---|---|
2013-01-01 | -3 | -13 | 晴~晴间多云 | 北风4-5级 |
2013-01-02 | -6 | -14 | 晴间多云 | 北风4-5级 |
2013-01-03 | -4 | -13 | 晴间多云~晴 | 无持续风向微风 |
2013-01-04 | -3 | -11 | 晴 | 无持续风向微风 |
2013-01-05 | -2 | -12 | 晴~晴间多云 | 无持续风向微风 |
1. 使用单个标签值查询
df.loc[row_label, column_label]
xxxxxxxxxx
# 查询单个值
temp = df.loc['2013-01-08', "最低温"]
print(temp)
# 查询一行,返回 Series
row = df.loc['2013-01-08']
print(row)
输出:
xxxxxxxxxx
-11
最高温 0
最低温 -11
天气 晴
风力风向 无持续风向微风
Name: 2013-01-08, dtype: object
2. 使用列表批量查询
xxxxxxxxxx
df.loc[['2013-06-03', '2013-06-04'], ['最高温', '天气']]
输出:
日期 | 最高温 | 天气 |
---|---|---|
2013-06-03 | 33 | 晴间多云~晴转多云 |
2013-06-04 | 26 | 阴有阵雨,北部地区有雷电 |
3. 使用切片进行范围查询
xxxxxxxxxx
df.loc['2013-06-01':'2013-06-05', '最低温':'风力风向']
输出:
日期 | 最低温 | 天气 | 风力风向 |
---|---|---|---|
2013-06-01 | 18 | 晴间多云~多云间阴,北部山区有阵雨 | 无持续风向微风 |
2013-06-02 | 18 | 阴有雾霾,午后-傍晚有雷阵雨~阴有雾霾,北部阵雨转晴 | 无持续风向微风 |
2013-06-03 | 19 | 晴间多云~晴转多云 | 无持续风向微风 |
2013-06-04 | 18 | 阴有阵雨,北部地区有雷电 | 无持续风向微风 |
2013-06-05 | 19 | 阴有时有阵雨,有雾~阴有零星小雨,有雾 | 无持续风向微风 |
4. 使用条件表达式查询
xxxxxxxxxx
# 查询全年最低温度小于-10度的所有数据
df.loc[df["最低温"] < -10]
输出: (部分)
日期 | 最高温 | 最低温 | 天气 | 风力风向 |
---|---|---|---|---|
2013-01-01 | -3 | -13 | 晴~晴间多云 | 北风4-5级 |
2013-01-02 | -6 | -14 | 晴间多云 | 北风4-5级 |
... | ... | ... | ... | ... |
xxxxxxxxxx
# 组合条件查询:用 & 连接,每个条件需用括号括起来
df.loc[(df["最低温"] > 0) & (df["最高温"] < 10)]
输出:
日期 | 最高温 | 最低温 | 天气 | 风力风向 |
---|---|---|---|---|
2013-04-19 | 6 | 2 | 小雨~阴 | 无持续风向微风 |
5. 调用函数查询
xxxxxxxxxx
# 使用 lambda 函数
df.loc[lambda df: (df["最高温"] < 12) & (df['最低温'] > 0)]
# 或者编写自己的函数
def query_september_warm_nights(df: pd.DataFrame):
# 查询9月份最低温大于等于18度的日子
return (df.index.str.startswith("2013-09")) & (df["最低温"] >= 18)
df.loc[query_september_warm_nights]
Pandas 新增数据列
1. 直接赋值
xxxxxxxxxx
# 新增“温差”列
df['温差'] = df['最高温'] - df['最低温']
df.head()
输出:
日期 | ... | 温差 |
---|---|---|
2013-01-01 | ... | 10 |
... | ... | ... |
2. 使用 df.apply
方法
apply
可以将一个函数应用到 DataFrame 的行或列上。
xxxxxxxxxx
def get_temperature_status(row):
if row["最高温"] > 30:
return "炎热"
elif row["最高温"] > 15:
return "舒适"
else:
return "寒冷"
# axis=1 表示按行应用函数
df["体感"] = df.apply(get_temperature_status, axis=1)
df.head()
输出:
日期 | ... | 温差 | 体感 |
---|---|---|---|
2013-01-01 | ... | 10 | 寒冷 |
... | ... | ... | ... |
3. 使用 df.assign
方法
assign
方法可以一次性添加多个新列,并返回一个新的 DataFrame 对象,原 DataFrame 不变。
xxxxxxxxxx
# 添加华氏温度列
df_new = df.assign(
最高温_华氏 = lambda x: x["最高温"] * 9 / 5 + 32,
最低温_华氏 = lambda x: x["最低温"] * 9 / 5 + 32
)
df_new.head()
4. 按条件选择分组分别赋值
xxxxxxxxxx
# 创建一个空列
df["温差等级"] = ''
# 对温差大于等于10的行,赋值 '大'
df.loc[df['温差'] >= 10, '温差等级'] = '大'
# 对温差小于10的行,赋值 '小'
df.loc[df['温差'] < 10, '温差等级'] = '小'
# 查看各等级的数量
print(df['温差等级'].value_counts())
输出:
xxxxxxxxxx
温差等级
大 213
小 152
Name: count, dtype: int64
Pandas 数据统计函数
1. 汇总类统计
df.describe()
可以快速获取所有数值列的汇总统计信息。
xxxxxxxxxx
df.describe()
mean()
, min()
, max()
等可以计算单个 Series 的统计值。
xxxxxxxxxx
print("全年平均最低温:", df['最低温'].mean())
print("全年最低温:", df['最低温'].min())
print("全年最高温:", df['最高温'].max())
输出:
xxxxxxxxxx
全年平均最低温: 8.12054794520548
全年最低温: -14
全年最高温: 37
2. 按值计数 value_counts()
xxxxxxxxxx
# 统计天气出现的次数
df['天气'].value_counts().head()
输出:
xxxxxxxxxx
天气
晴间多云 39
晴 25
晴~晴间多云 23
晴间多云~晴转多云 19
多云 10
Name: count, dtype: int64
3. 相关系数和协方差
协方差
cov()
: 衡量两个变量的同向/反向变化程度。相关系数
corr()
: 标准化后的协方差,衡量两个变量的线性相关性强弱,取值范围在[-1, 1]
之间。
xxxxxxxxxx
# 计算最高温和最低温的相关系数
# 注意:此操作前必须确保两列都为数值类型,否则会报错。
correlation = df['最高温'].corr(df['最低温'])
print(f"最高温与最低温的相关系数为: {correlation:.4f}")
# 计算所有数值列的相关系数矩阵
numeric_df = df[['最高温', '最低温', '温差']]
corr_matrix = numeric_df.corr()
print("\n相关系数矩阵:")
print(corr_matrix)
输出:
xxxxxxxxxx
最高温与最低温的相关系数为: 0.9315
相关系数矩阵:
最高温 最低温 温差
最高温 1.000000 0.931526 0.413589
最低温 0.931526 1.000000 -0.016545
温差 0.413589 -0.016545 1.000000
从结果可以看出,最高温和最低温有非常强的正相关性 (0.9315),符合常识。
0 评论:
发表评论