文章目录
最近在看关于机器学习的相关入门知识,在特征工程中使用了Numpy和Pandas提取样本特征和标签,后来了解到Pandas是一款基于Numpy的高级数据分析库,所以想学习下Pandas数据分析基础内容。
一、什么是Pandas
Pandas是Python 的核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。Pandas 的目标是成为 Python 数据分析实践与实战的必备高级工具,其长远目标是成为最强大、最灵活、可以支持任何语言的开源数据分析工具。
Pandas 适用于处理以下类型的数据:
- 与 SQL 或 Excel 表类似的,含异构列的表格数据
- 有序和无序(非固定频率)的时间序列数据
- 带行列标签的矩阵数据,包括同构或异构型数据
- 任意其它形式的观测、统计数据集, 数据转入 Pandas 数据结构时不必事先标记
异构型数据指的是数据的类型、来源不相同,一个数据表格含有不同类型和来源的数据时即为异构的。
Pandas 与 Numpy 的区别及优势:
Pandas 的主要数据结构是 Series(一维数据)与 DataFrame(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例。Pandas 基于 NumPy 开发,可以与其它第三方科学计算支持库完美集成,其优势如下:
- 处理浮点与非浮点数据里的缺失数据,表示为 NaN
- 大小可变:插入或删除 DataFrame 等多维对象的列
- 自动、显式数据对齐:显式地将对象与一组标签对齐,也可以忽略标签,在 Series、DataFrame 计算时自动与数据对齐
- 强大、灵活的分组(group by)功能:拆分-应用-组合数据集,聚合、转换数据
- 把 Python 和 NumPy 数据结构里不规则、不同索引的数据轻松地转换为 DataFrame 对象
- 基于智能标签,对大型数据集进行切片、花式索引、子集分解等操作
- 直观地合并(merge)、连接(join)数据集
- 灵活地重塑(reshape)、透视(pivot)数据集
- 轴支持结构化标签:一个刻度支持多个标签
- 成熟的 IO 工具:读取文本文件(CSV 等支持分隔符的文件)、Excel 文件、数据库等来源的数据,利用超快的 HDF5 格式保存 / 加载数据
- 时间序列:支持日期范围生成、频率转换、移动窗口统计、移动窗口线性回归、日期位移等时间序列功能
这些功能主要是为了解决其它编程语言、科研环境的痛点。处理数据一般分为几个阶段:数据整理与清洗、数据分析与建模、数据可视化与制表,Pandas 是处理数据的理想工具。
二、Pandas基本使用
使用前首先需要导入pandas和numpy库:
import pandas as pd
import numpy as np
2.1、数据结构使用
Pandas 的数据结构由 Series 和 DataFrame 组成,其中 Series 是一唯结构,DataFrame 是二维结构。使用 Series 可以表达数据行或列、使用 DataFrame 可以表达一个完整的二维数据表格,包含行(indexs)和列(columns)两个维度的描述信息。
- 创建Series
s = pd.Series([1, 2, 3, 4, 5, "", 7, np.nan])
print(s)
0 1
1 2
2 3
3 4
4 5
5
6 7
7 NaN
dtype: object
dtype指的是该行、该列或该范围内的数据类型
- 通过data、index及colums创建DataFrame
# data为5行3列的正态分布数据
data = np.random.randn(5, 3)
# indexs为5行日期范围数据
indexs = pd.date_range("2021-04-09", periods=5)
# columns为3列数据名称,分别为ABC
columns = list("ABC")
df = pd.DataFrame(data, index=indexs, columns=columns)
print(df)
A B C
2021-04-09 -1.165105 -0.008255 0.783923
2021-04-10 -1.248891 -0.916712 2.453062
2021-04-11 -1.214743 0.046706 -1.122817
2021-04-12 0.200107 -0.750826 1.108358
2021-04-13 1.271414 0.233218 1.087846
- 通过Series对象创建DataFrame
seriesMap = {"A": pd.Series([1, 2, 3, 4, 5]),
"B": pd.Series([4, 5, 6, 7, 8]),
"C": pd.Series([7, 8, 9, 10, 11]), }
df = pd.DataFrame(seriesMap)
df.index = indexs
print(df)
A B C
2021-04-09 1 4 7
2021-04-10 2 5 8
2021-04-11 3 6 9
2021-04-12 4 7 10
2021-04-13 5 8 11
2.2、描述性信息
使用Pandas可以很方便地查看数据的描述信息,比如查看前几行数据、行(索引)有哪些、列名称有哪些、查看数据整体中位数、平均值、第50%的数据的值等等:
df = pd.DataFrame(np.random.randn(5, 3), index=pd.date_range("2021-04-09", periods=5), columns=list("ABC"))
print("dataFrame:", df)
# 查看前两行数据
c = df.head(2)
print("head(2):", c)
# 查看后两行数据
c = df.tail(2)
print("tail(2):", c)
# 查看索引信息
c = df.index
print("index:", c)
# 查看列信息
c = df.columns
print("colunms:", c)
# 查看数据描述信息
c =df.describe()
print("describe():\n", c)
dataFrame:
A B C
2021-04-09 -0.026689 1.342181 -0.731386
2021-04-10 1.576142 -0.397611 -0.679097
2021-04-11 -2.239664 1.275189 -0.900623
2021-04-12 -2.164263 -0.503823 0.155695
2021-04-13 -0.404741 -0.513738 -0.760377
head(2):
A B C
2021-04-09 -0.026689 1.342181 -0.731386
2021-04-10 1.576142 -0.397611 -0.679097
tail(2):
A B C
2021-04-12 -2.164263 -0.503823 0.155695
2021-04-13 -0.404741 -0.513738 -0.760377
index:
DatetimeIndex(['2021-04-09', '2021-04-10', '2021-04-11', '2021-04-12',
'2021-04-13'],
dtype='datetime64[ns]', freq='D')
colunms:
Index(['A', 'B', 'C'], dtype='object')
describe():
A B C
count 5.000000 5.000000 5.000000
mean -0.651843 0.240439 -0.583158
std 1.598779 0.976519 0.421091
min -2.239664 -0.513738 -0.900623
25% -2.164263 -0.503823 -0.760377
50% -0.404741 -0.397611 -0.731386
75% -0.026689 1.275189 -0.679097
max 1.576142 1.342181 0.155695
2.3、迭代及排序
Pandas提供了数据迭代及排序功能,和字典的遍历类似,可以迭代获取到列Series和行Series对象。排序则使用sort_values方法及sort_indexs方法。
df = pd.DataFrame(np.random.randn(3, 2), index=pd.date_range("2021-04-09", periods=3), columns=list("AB"))
print("dataFrame:\n", df)
# 按列迭代,获取到每列的Series对象
for name, colSeries in df.items():
print(name)
print(colSeries)
# 按行迭代,获取到每行的Series对象
for name, rowSeries in df.iterrows():
print(name)
print(rowSeries)
dataFrame:
A B
2021-04-09 -1.479785 0.626420
2021-04-10 1.528794 0.622432
2021-04-11 -0.530254 0.931859
A
2021-04-09 -1.479785
2021-04-10 1.528794
2021-04-11 -0.530254
Freq: D, Name: A, dtype: float64
B
2021-04-09 0.626420
2021-04-10 0.622432
2021-04-11 0.931859
Freq: D, Name: B, dtype: float64
2021-04-09 00:00:00
A -1.479785
B 0.626420
Name: 2021-04-09 00:00:00, dtype: float64
2021-04-10 00:00:00
A 1.528794
B 0.622432
Name: 2021-04-10 00:00:00, dtype: float64
2021-04-11 00:00:00
A -0.530254
B 0.931859
Name: 2021-04-11 00:00:00, dtype: float64
注意,不可以在迭代过程之中修改数据,这不会生效,可以使用apply函数来进行迭代数据修改。建议在需要获取行和列数据的场景下,使用选择器loc或iloc来获取指定的数据,而不是通过迭代的方式,因为这种方式效率很低。
2.4、索引重建
索引重建的作用是将原数据按指定的索引顺序进行重建,当重建选择的索引不存在时,则会生成NAN空值。
df = pd.DataFrame(np.random.randn(3, 2), index=pd.date_range("2021-04-09", periods=3), columns=list("AB"))
print("dataFrame:\n", df)
print(df.index)
# 按行进行索引重建
c = df.reindex(index=pd.DatetimeIndex(['2021-04-11', '2021-04-09', '2021-04-12']))
print(c)
# 按列进行索引重建
c = df.reindex(columns=["B", "C"])
print(c)
# 同时按行与列进行索引重建
c = df.reindex(index=pd.DatetimeIndex(['2021-04-11', '2021-04-09', '2021-04-12']), columns=["B", "C"])
print(c)
dataFrame:
A B
2021-04-09 -0.455611 0.451562
2021-04-10 1.039412 -0.263696
2021-04-11 -0.235964 1.337724
DatetimeIndex(['2021-04-09', '2021-04-10', '2021-04-11'], dtype='datetime64[ns]', freq='D')
A B
2021-04-11 -0.235964 1.337724
2021-04-09 -0.455611 0.451562
2021-04-12 NaN NaN
B C
2021-04-09 0.451562 NaN
2021-04-10 -0.263696 NaN
2021-04-11 1.337724 NaN
B C
2021-04-11 1.337724 NaN
2021-04-09 0.451562 NaN
2021-04-12 NaN NaN
2.5、apply函数
在Pandas中,apply函数经常会被使用到,apply可以沿着DataFrame的横轴或者纵轴进行如统计、数据转化等操作。
pd.set_option('display.max_columns', 8) # 打印最大列数
df = pd.DataFrame(np.random.randn(3, 2), index=pd.date_range("2021-04-09", periods=3), columns=list("AB"))
print("dataFrame:\n", df)
# 列方向生成平均值
df.loc["mean1"] = df.apply(np.mean, axis=0)
# 行方向生成平均值
df["mean2"] = df.apply(np.mean, axis=1)
# 列方向生成最大值于最小值之差
df.loc["max1-min1"] = df.apply(lambda x: x.max() - x.min(), axis=0)
# 行方向生成最大值于最小值之差
df["max2-min2"] = df.apply(lambda x: x.max() - x.min(), axis=1)
# 列方向生成数值累加结果
df.loc["sum1"] = df.apply(np.sum, axis=0)
# 行方向生成数值累加结果
df["sum2"] = df.apply(np.sum, axis=1)
# 列方向生成第一行与第二行相乘结果
df.loc["x1"] = df.apply(lambda x: x[0] * x[1], axis=0)
# 行方向生成第一行与第二行相乘结果
df["x2"] = df.apply(lambda x: x[0] * x[1], axis=1)
# 将A列每个小于0的数据都转化为正数
df["A"] = df["A"].apply(lambda x: -1 * x if x < 0 else x)
print(df)
A B mean2 max2-min2 sum2 \
2021-04-09 00:00:00 0.370662 0.910307 0.269823 1.280969 2.090438
2021-04-10 00:00:00 1.256207 -0.582235 0.336986 1.838442 2.849401
2021-04-11 00:00:00 1.004682 -0.252607 0.376038 1.257288 2.385401
mean1 0.630076 0.025155 0.327616 0.604920 1.587767
max1-min1 1.626869 1.492542 0.106215 1.520655 4.746281
sum1 4.147172 1.593164 1.416677 6.502275 13.659287
x1 0.465628 -0.530013 0.090927 2.354988 5.956496
x2
2021-04-09 00:00:00 -0.337416
2021-04-10 00:00:00 -0.731408
2021-04-11 00:00:00 -0.253789
mean1 0.015850
max1-min1 2.428171
sum1 6.607124
x1 0.246789
2.6、字符串处理
Pandas对字符串的处理也有相应的支持,对于Series来说,使用.str 即可获取到字符串对象,并且可以进行相应的操作:
s = pd.Series(["Pandas", "Numpy", "tensorFlow"])
print("dataFrame:\n", s)
# 转为小写
c = s.str.lower()
print(c)
# 转为大写
c = s.str.upper()
print(c)
# 判断字符串是否含有Numpy
c = s.str.contains("Numpy")
print(c)
# 将Numpy替换为Java
c = s.str.replace("Numpy", "Java")
print(c)
# 获取首字母
c = s.str.get(0)
print(c)
# 字符串切片
c = s.str.slice(0, 2)
print(c)
# 计算字符出现次数
c = s.str.count("n")
print(c)
# 获取字符串长度
c = s.str.len()
print(c)
dataFrame:
0 Pandas
1 Numpy
2 tensorFlow
dtype: object
0 pandas
1 numpy
2 tensorflow
dtype: object
0 PANDAS
1 NUMPY
2 TENSORFLOW
dtype: object
0 False
1 True
2 False
dtype: bool
0 Pandas
1 Java
2 tensorFlow
dtype: object
0 P
1 N
2 t
dtype: object
0 Pa
1 Nu
2 te
dtype: object
0 1
1 0
2 1
dtype: int64
0 6
1 5
2 10
dtype: int64
2.7、索引及选择器
Pandas的DataFrame选择器可以通过行名称范围、列名称范围(loc)或行索引范围、行索引范围(iloc)进行选择,提取出新的DataFrame。
data_frame = pd.DataFrame(np.random.randn(5, 5), index=pd.date_range("20210405", periods=5), columns=list("ABCDE"))
print("data_frame:\n", data_frame)
# 获取某列
print("B columns:\n", data_frame["B"])
# 获取切片行
print("slice rows:\n", data_frame[0:2])
print("slice rows2:\n", data_frame["2021-04-05":"2021-04-08"])
# 选择多列
print("columns:\n", data_frame.loc["2021-04-05":"2021-04-08", ["A", "B"]])
# 获取2021-04-07中B列的值
print("loc 2021-04-07:B\n", data_frame.loc["2021-04-07", "B"])
# 按照索引选择
print("index choose 1, 1:\n", data_frame.iloc[1, 1])
print("index choose range 1:3, 0:2:\n", data_frame.iloc[1:3, 0:2])
# 选择全部行,但只需要A列
print("index choose all, column=A:\n", data_frame.loc[:, ["A"]])
data_frame:
A B C D E
2021-04-05 -1.433758 1.006381 -1.397154 0.745768 -0.665766
2021-04-06 1.524297 -0.417659 1.047648 -1.261089 -0.459849
2021-04-07 0.601041 -0.113164 0.168845 -0.321177 -0.812215
2021-04-08 0.786380 -1.027715 0.941147 -0.261271 0.849009
2021-04-09 2.272274 0.041790 1.140555 1.159317 1.847053
B columns:
2021-04-05 1.006381
2021-04-06 -0.417659
2021-04-07 -0.113164
2021-04-08 -1.027715
2021-04-09 0.041790
Freq: D, Name: B, dtype: float64
slice rows:
A B C D E
2021-04-05 -1.433758 1.006381 -1.397154 0.745768 -0.665766
2021-04-06 1.524297 -0.417659 1.047648 -1.261089 -0.459849
slice rows2:
A B C D E
2021-04-05 -1.433758 1.006381 -1.397154 0.745768 -0.665766
2021-04-06 1.524297 -0.417659 1.047648 -1.261089 -0.459849
2021-04-07 0.601041 -0.113164 0.168845 -0.321177 -0.812215
2021-04-08 0.786380 -1.027715 0.941147 -0.261271 0.849009
columns:
A B
2021-04-05 -1.433758 1.006381
2021-04-06 1.524297 -0.417659
2021-04-07 0.601041 -0.113164
2021-04-08 0.786380 -1.027715
loc 2021-04-07:B
-0.11316367868153508
index choose 1, 1:
-0.4176591189836492
index choose range 1:3, 0:2:
A B
2021-04-06 1.524297 -0.417659
2021-04-07 0.601041 -0.113164
index choose all, column=A:
A
2021-04-05 -1.433758
2021-04-06 1.524297
2021-04-07 0.601041
2021-04-08 0.786380
2021-04-09 2.272274
2.8、合并连接数据
这篇文章讲得很清楚:
https://blog.youkuaiyun.com/weixin_38168620/article/details/80663892
Pandas中合并连接数据主要使用merge、join以及concat方法。
- merge方法类似于SQL中的表连接操作,可选的连接方式也有(左右)外连接、内连接、按索引连接、按指定列连接等。
- join和merge一样用于连接多个DataFrame对象,但是一般用于无条件连接,将不规则的数据集拼接。
- concat连接可以理解为数据的垂直分表及水平分表后的数据集连接,主要作用是将不同的小数据集追加成大数据集。
2.9、分组及聚合
Pandas提供分组及聚合查询的功能,主要使用groupby函数来分组,agg函数用以做数据的聚合,分组聚合用于解决类似于"按班纬度来统计各班有多少人"这类问题,在数据分析过程中是十分常用的。注意,使用了分组操作后,就需要分组数据进行聚合,分组-聚合操作是同时出现的,但聚合操作可以单独使用。
关于分组及聚合,这篇文章讲得很好:https://zhuanlan.zhihu.com/p/101284491
-
分组groupby的原理是按照一定的分组条件,将相同条件的数据划分到同一个字典中,然后不同的分组字典重新组成一个完整的DataFrame对象。
-
聚合agg对不同的分组执行聚合操作,通常有取min、max、sum、mean、median、std、var、count。
2.10、缺失值处理
Pandas作为一款可以读取异构数据的分析库,由于可以一个Series和DataFrame可以容纳多种类型,所以就算数据中存在空值但仍然能被读取到,Series及DataFrame中空值以NaN、NaT表示,其中NaN表示普通数据空值,NaT表示时间类数据空值。
主要使用以下四类函数来处理及判断空值:
- df.dropna():以行或列的纬度删除具备空值的行或列,可以指定空值出现次数
- df.fillna():以行或列的纬度,按一定要求填充空值,比如可以用空值的前一个数据填充空值,或者指定值来填充空值。填充空值主要是为了方便后续对数据进行分析。
- df.isna():判断是否存在空值,以boolean矩阵形式返回。
2.11、IO工具
Pandas的I/O API是一组read函数,常用的有read_csv() read_excel 函数等,这类函数可以从指定的文件路径读取到携带文件数据到DataFrame对象:
- read_csv():该方法读取csv类文件,csv指的是“分隔符划分文件”,也就是采用特定分隔符来划分数据的一种文件,通常以.csv/.tsv/.txt 作为文件后缀,假定有以下csv文件(temp.csv):
S.No Name Age City Salary
0 1 Tom 28 Toronto 20000
1 2 Lee 32 HongKong 3000
2 3 Steven 43 Bay Area 8300
3 4 Ram 38 Hyderabad 3900
则读取方式为:
# 指定读取文件路径为temp.csv, 分隔符为\t,索引为S.No,
# 将Salary字段转化为float64类型
pandas.read_csv("temp.csv", sep='\t', index_col=["S.No"], dtype={'Salary': np.float64}
S.No Name Age City Salary
0 1 Tom 28 Toronto 20000.0
1 2 Lee 32 HongKong 3000.0
2 3 Steven 43 Bay Area 8300.0
3 4 Ram 38 Hyderabad 3900.0
三、练习题目
看完了基础可以试着按这套练习走一遍,可以加深对Pandas数据分析过程的理解。
1638



被折叠的 条评论
为什么被折叠?



