Python数据分析之Pandas

前言

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’
  • delimitersep
  • 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='#')

pandas_01_read_table

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')

pandas_02_read_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')

pandas_03_read_excel

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")

pandas_04_read_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)

pandas_05_read_sql

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]

pandas_06_read_html

可通过 df.to_html 转为html

1.7 latex

pandas 可以通过df.to_latex 将数据转为 latex 表格

二、数据结构

2.1 一维数据 Series

Series 是 带有 标签的一维 ndarray(包括时间Series),默认用0到n-1来作为 Series 的 index。

文档地址:

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 最常用的也就是它

文档地址:

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"])

pandas_07_df_create

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()
    

    pandas_08_df_info

  • 查看行列数据

    使用head(), tail() 查看头或尾几行数据, 使用get() 获取第几列

    df.head(2)
    df.tail(2)
    df.get(['b', 'c'])
    
    df[0:2]
    

    pandas_09_df_head_tail

2.2.2 数据遍历

  • 按行遍历

    for index, row in df.iterrows():
        print("索引{} 行数据:{}".format(index, row))
    

    pandas_10_df_iterate_01

  • 按列遍历

    for index,col in df.iteritems():
        print("列索引{} 列数据:{}".format(index, col))
    

    pandas_10_df_iterate_col_02

2.2.3 数据选取

  • 获取某行某列数据

    df.at[2, 'c']
    

pandas_11_df_find_at

  • 获取行数据

    df[1:3]
    df.loc[1:3]
    df.loc[1]
    

pandas_12_df_loc_row

  • 获取列数据

    df['a']
    df[['c', 'a']]
    df.loc[:, 'a']
    

pandas_13_df_loc_col

  • 获取部分数据

    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)]
    

    pandas_14_df_loc_some_data

2.2.4 数据处理

  • 添加

    # 行添加
    df.loc[3]=[10, 11, 12]
    df.loc[4]=[13, 14, 15]
    
    # 列添加
    df['d'] = df['a'] * 2
    

pandas_15_df_add_data

  • 删除

    # 删除行
    df.drop([3, 4])
    
    # 删除列
    df.drop(['d'], axis=1)
    

pandas_16_df_drop_data

2.2.5 数据统计

df.groupby(by="a").sum()

df.agg(['sum', 'min'])

df.sort_values(by=['a'], ascending=False)
df.sort_index(ascending=False)

pandas_17_df_agg

2.3 索引对象 Index

用于索引和对齐的不可变序列。 存储所有 Pandas 对象的轴标签的基本对象。使用index的好处有:

  1. 方便的数据查询
  2. 提升查询性能
  3. 自动对齐数据
  4. 更强大的数据结构支持

文档: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))
    

    pandas_18_df_arange_index

  • 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')
    

    pandas_19_df_date_index

  • pd.PeriodIndex

    保持表示规则时间周期的有序索引

    idx = pd.PeriodIndex(year=[2020, 2022], quarter=[1, 3])
    pd.DataFrame(data=np.arange(0, 4, 2), index=idx)
    

    pandas_20_df_date_period_index

  • pd.CategoricalIndex

    分类索引,像分类一样,只能接受有限的、通常是固定的可能值(类别)

    pd.CategoricalIndex(["S","M","L","XS","M","L","S","M","L","XL"],categories=["XS","S","M","L","XL"],ordered=True,name="category")
    

pandas_21_df_categorial_index

2.4 时间戳 TimeStamp

Pandas 内部有个替代Python datetime.datetime对象的类TimeStamp,能够相互转化,

文档地址:http://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Timestamp.html

pandas_21_timestamp

三、窗口函数

http://pandas.pydata.org/pandas-docs/stable/reference/window.html

3.1 滚动窗口函数 rolling

rolling 函数生成滚动对象 Rolling,有很多函数可以使用,SeriesDataFrame 都可以调用 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()   # 排名

pandas_22_rolling

3.2 扩展窗口 expanding

expanding 函数和rolling 类似,rolling是固定宽度滚动,而expanding是拓展宽度,给定参数一般是最小宽度,然后拓展

df.expanding(2).count()
df.expanding(1).sum()

pandas_23_expanding

四、分组

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'})

pandas_24_groupby

4.2 转化

pandas_25_groupby_agg

  • apply

    apply可以应用一些自定义的函数

    # 每个班级语文平均分 和数学平均分的差值
    df.groupby('班级').apply(lambda x: x['语文'].mean() - x['数学'].mean())
    

pandas_26_groupby_apply

  • 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)
    

    pandas_27_groupby_transform

4.3 合并

参考

  1. Pandas的索引index
  2. 详解pandas中的rolling
  3. AI scipy stats .峰度()函数| Python
  4. Pandas中groupby的这些用法
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aabond

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值