文章目录
- 前言
- 一、输入输出
- 1.1 txt
- 1.2 csv
- 1.3 excel
- 1.4 json
- 1.5 sql
- 1.6 html
- 1.7 latex
- 二、数据结构
- 2.1 一维数据 Series
- 2.2 二维数据 DataFrame
- 2.2.1 数据查看
- 2.2.2 数据遍历
- 2.2.3 数据选取
- 2.2.4 数据处理
- 2.2.5 数据统计
- 2.3 索引对象 Index
- 2.4 时间戳 TimeStamp
- 三、窗口函数
- 3.1 滚动窗口函数 rolling
- 3.2 扩展窗口 expanding
- 四、分组
- 4.1 分组groupby
- 4.2 转化
- 4.3 合并
- 参考
前言
Pandas: 功能强大的Python数据分析工具包,主要特点:
- 易于处理浮点和非浮点数据中的缺失数据(表示NaN、NA或NaT)
- 大小可变性:可以从数据框架和更高维对象中插入和删除列
- 自动和显式的数据对齐:对象可以显式地对齐到一组标签,或者用户可以简单地忽略标签,让系列、数据帧等。在计算中自动为您对齐数据
- 功能强大、灵活的分组功能,对数据集执行拆分应用组合操作,用于聚合和转换数据
- 使将其他Python和NumPy数据结构中的不规则、不同索引的数据转换为数据框架对象变得容易
- 基于标签的智能切片、花哨的索引和大型数据集的子集
- 直观的合并和连接数据集
- 灵活的重塑和旋转的数据集
- 轴的层次标记(可有多个标签)
- 强大的IO工具:能从文本文件(CSV 文件或分隔符分隔的文本)、Excel文件、数据库加载数据,还可以从超快速的 HDF5 格式保存/加载数据
- 特定于时间序列的功能:日期范围生成和频率转换、移动窗口统计数据、日期转移和滞后
github 地址:https://github.com/pandas-dev/pandas
文档地址:http://pandas.pydata.org/pandas-docs/stable/
安装
pip install pandas
一、输入输出
pandas 提供十几种类型的文件格式便于开发者读取和写入,下面会介绍一些常用的
1.1 txt
读取文本文件可以使用 read_table() 函数,用于将分隔好的数据读取为 DataFrame
文档地址:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_table.html#pandas.read_table
常用参数:
- sep 分隔符,默认’\t’
- delimiter 同 sep
- header 用作列名的行号和数据的开头, 默认推断
- names 要使用的列名的列表。如果文件包含一个头行,则应该显式地传递header=0来覆盖列名。不允许在此列表中进行重复操作。
- decimal 数字的分隔符,默认’.‘。欧洲常用’,’
- comment 表示不应解析该行的其余部分。如果在一行的开头找到,则该行将被完全忽略。此参数必须是单个字符。
- index_col 用作数据框架的行标签,可以作为字符串名称或列索引。默认为 None
- usecols
测试 txt 文件: https://github.com/AxelPaivansalo/GPR-prediction-program-scientific/blob/main/data/raw_data/DMTA_Stora05_BC075_1Hz.txt
# Test: DMTA_Stora05_BC075_1Hz
# Result: Temperature (up)
# Interval: 1
Point No. Time(s) Test Time(s) Temperature(C) Storage Modulus(Pa) Loss Modulus(Pa) Loss Factor(1) Complex Viscosity(Pa*s*10^-3) Torque(N*m*10^-6) Status Complex Shear Modulus(Pa) Phase Shift Angle(rad)
1 30,000 942,2 28,60 13,606 12,653 0,93 2957,1 2,2276 TruStrain™ 18,58 0,75
2 60,000 972,2 27,09 13,578 12,637 0,931 2952,1 2,2239 TruStrain™ 18,549 0,75
3 90,000 1002 25,64 13,516 12,614 0,933 2942,5 2,2167 TruStrain™ 18,488 0,75
4 120,000 1032 24,34 13,563 12,699 0,936 2957,1 2,2276 TruStrain™ 18,58 0,75
5 150,000 1062 23,17 13,601 12,789 0,94 2971,3 2,2384 TruStrain™ 18,669 0,75
6 180,000 1092 22,09 13,598 12,868 0,946 2979,7 2,2447 TruStrain™ 18,722 0,76
7 210,000 1122 21,14 13,613 12,97 0,953 2992,6 2,2544 TruStrain™ 18,803 0,76
8 240,000 1152 20,37 13,605 13,089 0,962 3004,7 2,2635 TruStrain™ 18,879 0,77
9 270,000 1182 19,82 13,632 13,207 0,969 3020,8 2,2757 TruStrain™ 18,98 0,77
import pandas as pd
import numpy as np
pd.read_table('DMTA_Stora05_BC075_1Hz.txt', decimal=',', comment='#')
1.2 csv
csv 文件是一种特殊的文本文件,可以用上面的read_table, 也可以使用pd.read_csv()
文档:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html
read_csv 和 read_table 常用参数类似
csv 例子文件:https://github.com/MonadWizard/pandas_Demo/blob/master/merging_joining_and_concatenating/Restaurant%20-%20Customers.csv
pd.read_csv('./Desktop/Restaurant - Customers.csv')
csv 文件的写入可以用 DataFrame.to_csv()
1.3 excel
excel 文件可以用 pd.read_excel()
文档:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_excel.html
常用参数和 read_table 类似,还多了下面
- sheet_name excel sheet 名字,默认0表示第一个sheet, None表示所有
excel 例子文件:https://github.com/MonadWizard/pandas_Demo/blob/master/InputAndOutput_excel/Data%20-%20Single%20Worksheet.xlsx
pd.read_excel('./Desktop/Data - Single Worksheet.xlsx')
excel 文件的写入可以见:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_excel.html
1.4 json
json 数据也可以通过 pd.read_json 来读取
文档:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_json.html
常用参数
- typ: 要恢复的类型,可选{‘frame’, ‘series’}, 默认 ‘frame’
- compression:对磁盘数据动态解压缩,字符串或字典,默认推断
- lines: 是否将文件的每行作为 json 对象读取,默认false
json 文件例子:https://github.com/cswanson618/DarkSkyProject/blob/master/json_by_state/United%20States%20-%20Alabama.json
pd.read_json("./Desktop/United States - Alabama.json")
保存为json 数据可以用 df.to_json()
1.5 sql
pandas 可以连接数据库,通过sql读取数据库数据
文档:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_sql.html
测试 sql 文件
CREATE TABLE `blog` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`author_id` int(11) NOT NULL,
`title` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
)
INSERT INTO `test`.`blog` (`id`, `author_id`, `title`) VALUES ('1', '101', 'Jim Business');
INSERT INTO `test`.`blog` (`id`, `author_id`, `title`) VALUES ('2', '1121', 'Bally Slog');
import pymysql
from sqlalchemy import create_engine
engine = create_engine("mysql+pymysql://root:root@localhost:3306/test")
conn = engine.connect()
pd.read_sql("select * from blog", engine)
1.6 html
pandas 可以通过read_html() 读取 html 中表格数据
文档地址:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_html.html
pd.read_html('https://www.basketball-reference.com/leagues/NBA_2020_games-october-2019.html')[0]
可通过 df.to_html 转为html
1.7 latex
pandas 可以通过df.to_latex 将数据转为 latex 表格
二、数据结构
2.1 一维数据 Series
Series 是 带有 标签的一维 ndarray(包括时间Series),默认用0到n-1来作为 Series 的 index。
文档地址:
- http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.html
- http://pandas.pydata.org/pandas-docs/stable/user_guide/dsintro.html#series
s1 = pd.Series([1, 3, 5, np.nan, 6, 8])
s2 = pd.Series(np.random.randn(5), index=["a", "b", "c", "d", "e"])
d = {"b": 1, "a": 0, "c": 2}
s3 = pd.Series(d)
s4 = pd.Series(d, index=["a", "b", "c", "d"])
s5 = pd.Series(5.0, index=["a", "b", "c", "d", "e"])
2.2 二维数据 DataFrame
DataFrame 是二维数据结构,和 Excel,数据库中的表类似。pandas 最常用的也就是它
文档地址:
- http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html#pandas.DataFrame
- http://pandas.pydata.org/pandas-docs/stable/user_guide/dsintro.html#dataframe
data1 = [{"a": 1, "b": 2}, {"a": 5, "b": 10, "c": 20}]
pd.DataFrame(data1)
pd.DataFrame(data1, index=["first", "second"])
pd.DataFrame(data1, columns=["a", "b"])
2.2.1 数据查看
-
查看数据信息
通过 shape info() describe() 查看数据形状几行几列 等一些具体信息
df = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c']) df.shape df.info() df.describe()
-
查看行列数据
使用head(), tail() 查看头或尾几行数据, 使用get() 获取第几列
df.head(2) df.tail(2) df.get(['b', 'c']) df[0:2]
2.2.2 数据遍历
-
按行遍历
for index, row in df.iterrows(): print("索引{} 行数据:{}".format(index, row))
-
按列遍历
for index,col in df.iteritems(): print("列索引{} 列数据:{}".format(index, col))
2.2.3 数据选取
-
获取某行某列数据
df.at[2, 'c']
-
获取行数据
df[1:3] df.loc[1:3] df.loc[1]
-
获取列数据
df['a'] df[['c', 'a']] df.loc[:, 'a']
-
获取部分数据
df.iloc[[0, 1], [1, 2]] df.iloc[1:3, 0:3] df.loc[df['a'] >= 2] df.loc[(df['a'] >= 2) & (df['a'] < 7)]
2.2.4 数据处理
-
添加
# 行添加 df.loc[3]=[10, 11, 12] df.loc[4]=[13, 14, 15] # 列添加 df['d'] = df['a'] * 2
-
删除
# 删除行 df.drop([3, 4]) # 删除列 df.drop(['d'], axis=1)
2.2.5 数据统计
df.groupby(by="a").sum()
df.agg(['sum', 'min'])
df.sort_values(by=['a'], ascending=False)
df.sort_index(ascending=False)
2.3 索引对象 Index
用于索引和对齐的不可变序列。 存储所有 Pandas 对象的轴标签的基本对象。使用index的好处有:
- 方便的数据查询
- 提升查询性能
- 自动对齐数据
- 更强大的数据结构支持
文档:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Index.html#pandas.Index
下面介绍几种常用索引:
-
pd.RangeIndex
连续的整数索引。当用户不提供显式索引时,这是DataFrame和Series所使用的默认索引类型
pd.RangeIndex(0, 10, 2) pd.DataFrame(data=np.arange(0, 10, 2), index=pd.RangeIndex(0, 10, 2))
-
pd.DatetimeIndex
时间索引,可以用pd.date_range生成,默认为天
rg=pd.DatetimeIndex(['2023-01-01','2023-01-02','2023-01-03','2023-01-04']) pd.DataFrame(data=np.arange(0, 8, 2), index=rg) pd.date_range(start='2023-01-01', end='2023-01-04')
-
pd.PeriodIndex
保持表示规则时间周期的有序索引
idx = pd.PeriodIndex(year=[2020, 2022], quarter=[1, 3]) pd.DataFrame(data=np.arange(0, 4, 2), index=idx)
-
pd.CategoricalIndex
分类索引,像分类一样,只能接受有限的、通常是固定的可能值(类别)
pd.CategoricalIndex(["S","M","L","XS","M","L","S","M","L","XL"],categories=["XS","S","M","L","XL"],ordered=True,name="category")
2.4 时间戳 TimeStamp
Pandas 内部有个替代Python datetime.datetime对象的类TimeStamp,能够相互转化,
文档地址:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Timestamp.html
三、窗口函数
http://pandas.pydata.org/pandas-docs/stable/reference/window.html
3.1 滚动窗口函数 rolling
rolling 函数生成滚动对象 Rolling,有很多函数可以使用,Series 和 DataFrame 都可以调用 rolling 函数
函数名 | 含义 |
---|---|
count | 非NaN数量 |
sum | 和 |
mean | 平均值 |
median | 中位数 |
var | 方差 |
std | 标准差 |
min | 最小值 |
max | 最大值 |
corr | 相关系数 |
cov | 样本协方差 |
skew | 无偏偏度 |
kurt | 峰度 |
apply | 自定义聚合函数 |
aggregate/agg | 聚合操作 |
quantile | 分位数 |
rank | 排名 |
df = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c'])
df.rolling(2).count() # 非NaN计数
df.rolling(2).sum() # 求和
df.rolling(2).mean() # 平均值
df.rolling(2).median() # 中位数
df.rolling(2).var() # 方差
df.rolling(2).std() # 标准差
df.rolling(2).min() # 最小值
df.rolling(2).max() # 最大值
df.rolling(2).corr() # 相关系数
df.rolling(2).cov() # 样本协方差
df.rolling(2).skew() # 无偏偏度
df.rolling(2).kurt() # 峰度 scipy.stats.kurtosis
df.rolling(2).apply(lambda x: x[0:1] + 1) # 自定义聚合函数
df.rolling(2).agg({"a": "sum", "b": "min", "c": "max"}) # 聚合操作
df.rolling(2).quantile(.4, interpolation='midpoint') # 分位数
df.rolling(2).rank() # 排名
3.2 扩展窗口 expanding
expanding 函数和rolling 类似,rolling是固定宽度滚动,而expanding是拓展宽度,给定参数一般是最小宽度,然后拓展
df.expanding(2).count()
df.expanding(1).sum()
四、分组
api 文档:http://pandas.pydata.org/pandas-docs/stable/reference/groupby.html
guide 文档:https://pandas.pydata.org/pandas-docs/stable/user_guide/groupby.html#splitting-an-object-into-groups
4.1 分组groupby
Series 和 DataFrame 都可以通过groupby 函数对数据进行分组,常用四个参数如下:
-
by,分组字段,可以是列名/Series/字典/函数,常用为列名
-
axis,指定切分方向,默认为0,表示沿着行切分,1为列 {0 or ‘index’, 1 or ‘columns’}, default 0
-
as_index,是否将分组列名作为输出的索引,默认为True;当设置为False时相当于加了reset_index功能
-
sort,与SQL中groupby操作会默认执行排序一致,该groupby也可通过sort参数指定是否对输出结果按索引排序
所有参数具体文档:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html#pandas.DataFrame.groupby
import pandas as pd
import numpy as np
df = pd.DataFrame({'班级': [1, 2, 2, 1, 3],
'姓名': ['张三', '李四', '王五', '张张','王二小'],
'语文': np.random.randint(20, 100, 5),
'数学': np.random.randint(20, 100, 5),
'英语': np.random.randint(20, 100, 5)})
df.groupby('班级').mean() # 针对班级分组, 计算平均数
df.groupby(df['姓名'].str[0]).mean() # 对姓名首个字符(姓)进行分组
person = {0: '男', 1: '女', 2: '女', 3: '男', 4: '男'}
df.groupby(person).agg({'语文': 'mean', '数学':'mean', '英语': 'mean'})
4.2 转化
-
agg
agg 是一个聚合函数,上述已经有一些例子。
更多文档:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.groupby.DataFrameGroupBy.aggregate.html
df.groupby('班级').agg({'语文': ['min', 'max'], '英语': ['min', 'max']})
-
apply
apply可以应用一些自定义的函数
# 每个班级语文平均分 和数学平均分的差值 df.groupby('班级').apply(lambda x: x['语文'].mean() - x['数学'].mean())
-
transform
transform并不对数据进行聚合输出,而只是对每一行记录提供了相应聚合结果
# 每个人和班级平均分对比 avg_df = df.groupby(['班级']).transform('mean').rename(columns={'语文':'语文平均分','数学':'数学平均分','英语':'英语平均分'}) pd.concat([df, avg_df], axis=1) diff_df = df.groupby(['班级']).transform(lambda x: x - x.mean()).rename(columns={'语文':'语文均分差值','数学':'数学均分差值','英语':'英语均分差值'}) pd.concat([df, avg_df, diff_df], axis=1)
4.3 合并
-
merge
数据库方式的数据连接,可根据一个或多个键,将不同DataFrame对象的行连接起来,详细文档:
- http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.merge.html
- http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.merge.html#pandas.merge
-
concat
轴向数据连接,沿着一条轴,将多个DataFrame对象堆叠到一起,详细文档:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html#pandas.concat
-
combine
用一个DataFrame对象中的数据填充另一个DataFrame对象中的缺失数据,详细文档:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.combine.html
df1 = pd.DataFrame({'班级': [1, 2, 2, 1, 3], '姓名': ['张三', '李四', '王五', '张张','王二小'], '美术': np.random.randint(60, 100, 5), '品德': np.random.randint(90, 100, 5)}) df.merge(df1)
参考
- Pandas的索引index
- 详解pandas中的rolling
- AI scipy stats .峰度()函数| Python
- Pandas中groupby的这些用法