Pandas新手教程

Pandas新手教程

pandas - Python Data Analysis Library

Getting started tutorials ; pandas 2.1.1 documentation

数据类型

1
import pandas as pd

DataFrame

1
2
# 创建DataFrame
df = pd.DataFrame({"列名": [列数据]})

DataFrame是二维数据结构,可以存储表形式的数据

Series

1
2
3
4
# 查看某列数据
df["列名"]
# 创建Series
column_data = pd.Series([列数据], name="列名")

Series是DataFrame的一列,没有行名和列名

DataFrame和Series的一些统计功能

1
2
3
4
5
6
df.describe()
df.count()
df.mean()
df.std()
df.max()
df.min()

表格形式数据的读写

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 读取各种格式的文件read_*(csv, excel, sql, json, ...)
data = pd.read_csv("data.csv")
# 查看前8行
data.head(8)
# 查看后10行
data.tail(10)
# 查看形状
data.shape
# 查看每列的数据类型
data.dtypes
# 写入各种格式的文件to_*(csv, excel, sql, json, ...)
data.to_excel("data.xlsx", sheet_name="data", index=False)
# 查看DataFrame的信息
data.info()

DataFrame数据筛选

1
2
3
4
5
6
7
8
9
10
11
12
13
# 选择特定列
data[["列名", ...]]
# 选择特定行
data[data["列名"] > 6] # data[条件表达式],==, !=, <, >, <=, >=, ...
data[data["列名"].isin([2, 3])] # 选择该列值为2或3的行
data[(data["列名"] == 2) | (data["列名"] == 3)] # 每个条件必须用()包围起来,并且只能使用|或&,不能使用or或and
data[data["列名"].notna()] # 选择该列值不为Null的行
# 选择特定的行和列
data.loc[data["列名"] > 6, "列名"] # data.loc[行, 列]
data.iloc[2:8, 3:9] # data.loc[行索引, 列索引]
# 指定单元的值
data.loc[data["列名"] == 6, "列名"] = "value"
data.iloc[0:3, 3] = "value"

画图

1
2
3
4
5
6
import matplotlib.pyplot as plt
data.plot() # 画DataFrame,索引为横轴
data["列名"].plot() # 画Series,索引为横轴
data.plot(x="列名1", y="列名2") # 点图,对比两列的值
data.plot.box() # 箱图
data.plot.area(subplots=True) # subplots=True每列单独作画

pandas创建的plot对象是Matplotlib,因此适用Matplotlib的所有功能,如下

1
2
3
4
5
fig, axs = plt.subplots(figsize=(12, 4))  # 创建空的Matplotlib的Figure和Axes
data.plot.area(ax=axs) # 使用pandas将area图画在准备好的Figure/Axes上
axs.set_ylabel("y轴标签") # 使用Matplotlib操作定制图片
fig.savefig("图片名.png") # 使用Matplotlib现成的方法保存Figure/Axes
plt.show() # 显示该图

从现有列中创建新列

1
2
3
4
5
# 元素级计算(+, -, *, /, <, >, ==, ...)
data["新列名"] = data["原列名"] * num
data["新列名"] = data["原列名1"] / data["原列名2"]
data_renamed = data.rename(columns={"原列名": "新列名",}, rows={"原行名": "新行名"})
data_renamed = data.rename(columns=str.lower) # 使用映射函数进行重命名

计算统计数据

聚合统计数据

1
2
3
4
5
# 列的统计数据,缺失数据不参与运算
data["列名"].mean()
data[["列名1", "列名2"]].median()
data[["列名1", "列名2"]].describe() # 多个统计数据
data.agg({"列名1": ["min", "max", "median", "skew"], "列名2": ["min", "max", "median", "mean"]}) #自定义列的统计数据

聚合按类别分组的统计信息

1
2
3
4
data[["列名1", "列名2"]].groupby("列名1").mean()  # 先选择两列,再按列1的类别进行分组,最后计算每个类别的平均值
data.groupby("列名").mean(numeric_only=True) # 计算每个数字列的均值
data.groupby("列名1")["列名2"].mean() # 仅计算选择列的均值
data.groupby(["列名1", "列名2"])["列名3"].mean() # 多列分组

计算类别的数量

1
2
data["列名"].value_counts()  # 计数,等同于下行,可用dropna参数选择是否计数缺失值
data.groupby("列名")["列名"].count() # count不计缺失值,size计数缺失值(即行数)

重塑表格

行排序

1
2
data.sort_values(by="列名")
data.sort_values(by=['列名1', '列名2'], ascending=False)

由长到宽

1
2
3
data.sort_index().groupby(["列名"]).head(2)  # 返回每个类别的前两行
data.pivot(columns="列名1", values="列名2") # 列1的类别作为新的列,列2的数据作为对应类别的值
data.pivot(columns="列名1", values="列名2").plot() # 画图

透视表

1
2
3
# pivot()数据仅仅只是重新排列,当多个值需要被聚合时,可以使用pivot_table(),该方法通过聚合函数将多个值结合起来
data.pivot_table(values="列名1", index="列名2", columns="列名3", aggfun="mean") # 列1上的平均值
data.pivot_table(values="列名1", index="列名2", columns="列名3", aggfun="mean", margins=True) # 求透视表的行列均值

由宽到长

1
2
3
data.reset_index()  # 新增索引
data.melt(id_vars="列名") # 将除了指定列以外的所有列融合成两列:一列的数据是列名,一列的数据是对应的值
data.melt(id_vars="列名1", value_vars=["作为变量的列的名字1", "作为变量的列的名字2", ...], value_name="值列的名字", var_name="变量列的名字") # 具体设置,value_vars定义哪些列要融合,value_name提供值列的名字(替代默认的value),var_name提供变量列的名字(替代默认的variable)

合并多表数据

拼接对象

1
2
data = pd.concat([data1, data2], axis=0)  # 默认axis=0拼接行,axis=1则拼接列
data = pd.concat([data1, data2], keys=["表一索引名", "表二索引名"]) # keys添加额外的层次行索引,用于识别原表

使用共同列联接表

1
2
data = pd.merge(data1, data2, how="left", on="共同列名")  # left联接,只使用data1(左表)的共同列的值进行联接
data = pd.merge(data1, data2, how="left", left_on="左表用于联接的列", right_on="右表用于联接的列")

处理时间序列

使用pandas的datetime属性

1
2
3
4
5
6
data["时间列列名"] = pd.to_datetime(data["时间列列名"])  # 初始时时间列的值是字符串,to_datetime将字符串转换为pandas.Timestamp对象
data = pd.read_csv("data.csv", parse_dates=["时间列列名"]) # 读取时就对时间进行转换
data["时间列列名"].max() - data["时间列列名"].min() # 求时间范围
data["新列名"] = data["时间列列名"].dt.month # 使用dt访问器可以访问时间相关的属性
data.groupby([data["时间列列名"].dt.weekday, "列名1"])["列名2"].mean() # 按一周七天的每天和列1值进行分组,求列2上的平均值
data.groupby(data["时间列列名"].dt.hour)["列名"].mean().plot() # 画出每个小时的平均值

datetime作为索引

1
2
3
4
# 对datetime索引进行操作
data.index.year
data.index.weekday
data["year-month-day": "year-month-day"].plot() # 画出时间范围内的数据,字符串需要是datetime形式

将时间序列重新采样到另一个频率

1
2
3
4
# datetime索引
data_monthly_max = data.resample("M").max() # 先按月分组,再取每组最大值
data_monthly_max.index.freq # 时间序列的频率
data.resample("D").mean().plot() # 画出每天的平均值

操作文本数据

1
2
3
4
5
data["列名"].str.lower()  # 全部转换为小写
data["新列名"] = data["列名"].str.split(",").str.get(0) # 以逗号分割字符串,取分割后的第一部分
data[data["列名"].str.contrains("字符串")] # 取包含给定字符串的行
data["列名"].str.len().idxmax() # 最长字符串的索引
data["列名"].replace({"值1": "新值1", "值2": "新值2", ...}) # 字符串替换

Pandas新手教程
https://wangaaayu.github.io/blog/posts/a34278f2/
作者
WangAaayu
发布于
2023年9月10日
更新于
2024年1月13日
许可协议