- 数据分析三巨头 Numpy、Pandas、Matplotlib
pandas 是Python data analysis 的缩写,是基于Numpy和matplotlib的数据分析库,pandas是在numpy的基础上实现的,所有pandas与numpy有一定的相似之处。
pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建。Pandas 是 Python (opens new window)的核心数据分析支持库,提供了快速、灵活、明确的数据结构,旨在简单、直观地处理关系型、标记型数据。Pandas 的目标是成为 Python 数据分析实践与实战的必备高级工具,其长远目标是成为最强大、最灵活、可以支持任何语言的开源数据分析工具。
pandas 适用于处理以下类型的数据:
Pandas 的主要数据结构是 Series (opens new window)(一维数据)与 DataFrame (opens new window)(二维数据),这两种数据结构足以处理金融、统计、社会科学、工程等领域里的大多数典型用例。对于 R 用户,DataFrame 提供了比 R 语言 data.frame 更丰富的功能。Pandas 基于 NumPy (opens new window)开发,可以与其它第三方科学计算支持库完美集成。
Pandas 就像一把万能瑞士军刀,下面仅列出了它的部分优势 :
NaN
;这些功能主要是为了解决其它编程语言、科研环境的痛点。处理数据一般分为几个阶段:数据整理与清洗、数据分析与建模、数据可视化与制表,Pandas 是处理数据的理想工具。
其它说明:
由于pandas是在numpy的基础上实现的,numpy最核心的数据结果是ndarray,numpy支持任意维数的数组,但要求单个数组内所有数据是同质的,即类型必须相同.而pandas的核心数据结构Pandas 的主要数据结构是 Series(一维数据)与 DataFrame(二维数据)。仅支持一维和二维数据,但数据内部可以是异构数据,仅要求同列数据类型一致即可。关于pandas两种数据结构的具体介绍,可移步至https://www.pypandas.cn/docs/getting_started/dsintro.html#series。除此之外,numpy主要是用于数值计算,尤其是内部集成了大量矩阵计算模块,例如基本的矩阵运算、线性代数、fft、生成随机数等,支持灵活的广播机制,而pandas主要用于数据处理与分析,支持包括数据读写、数值计算、数据处理、数据分析和数据可视化全套流程操作。
那么pandas为什么有多个数据结构呢,Pandas 数据结构就像是低维数据的容器。比如,DataFrame 是 Series 的容器,Series 则是标量的容器。使用这种方式,可以在容器中以字典的形式插入或删除对象。此外,通用 API 函数的默认操作要顾及时间序列与截面数据集的方向。多维数组存储二维或三维数据时,编写函数要注意数据集的方向,这对用户来说是一种负担;如果不考虑 C 或 Fortran 中连续性对性能的影响,一般情况下,不同的轴在程序里其实没有什么区别。Pandas 里,轴的概念主要是为了给数据赋予更直观的语义,即用“更恰当”的方式表示数据集的方向。这样做可以让用户编写数据转换函数时,少费点脑子。
import numpy as np
import pandas as pd
df = pd.DataFrame(pd.read_csv('heros.csv',header=1))
这里我读入的是一个csv文件,也支持其他类型的文件,改一下参数名就行。
如果这里报类型错误,pandas没有DataFrame,有几种情况:
1、pandas版本过低, pip install --upgrade pandas 更新一下安装包即可;
2、卸载已有的包,重新安装
pip uninstall pandas
pip install pandas
3、文件名或者包名包含了pandas或者其他关键字字样,都可能会报这个错误,使用创 建py文件以及你创建的包时,一定要注意书写。
# 1、head 以及 tail 命令
# head默认显示前五行数据,tail默认显示后五行数据
print(df.head())
print(df.tail())
# 结果:
# D:\python\envs\pythonProject\python.exe D:/python/project/数据分析/基础.py
# 7350 288.8 3307 1746 94 430 321 ... 98 3.357 51 37 1.571 15 近战
# 0 7000 275.0 3150 1760 95 430 318 ... 92 3.143 48 37 1.571 15 近战
# 1 8341 329.4 3450 100 0 100 301 ... 115 4.143 57 5 0.000 5 近战
# 2 8476 352.8 3537 1926 104 470 273 ... 117 4.214 58 42 1.786 17 近战
# 3 7344 270.0 3564 0 0 0 343 ... 97 3.071 54 0 0.000 0 近战
# 4 8050 316.3 3622 0 0 0 346 ... 106 3.643 55 0 0.000 0 近战
#
# [5 rows x 19 columns]
# 7350 288.8 3307 1746 94 430 321 ... 98 3.357 51 37 1.571 15 近战
# 63 5968 192.8 3269 0 0 0 427 ... 81 2.214 50 0 0.000 0 近战
# 64 6205 211.9 3239 1808 97 450 385 ... 79 2.286 47 38 1.571 16 近战
# 65 6232 210.0 3292 1822 98 450 388 ... 99 3.357 52 46 1.929 19 近战
# 66 6700 237.5 3375 1784 96 440 328 ... 81 2.643 44 38 1.571 16 近战
# 67 5611 185.1 3019 1784 96 440 410 ... 68 2.071 39 38 1.571 16 远程
#
# [5 rows x 19 columns]
# 2 提取数据,推荐用.__array__() .to_numpy()
print(df.to_numpy())
print(df.__array__())
结果:
[[7000 275.0 3150 ... 1.571 15 '近战']
[8341 329.4 3450 ... 0.0 5 '近战']
[8476 352.8 3537 ... 1.786 17 '近战']
...
[6232 210.0 3292 ... 1.929 19 '近战']
[6700 237.5 3375 ... 1.571 16 '近战']
[5611 185.1 3019 ... 1.571 16 '远程']]
Process finished with exit code 0
df.shape #维度查看,与numpy一样
df.info() #表结构查看
print(df.dtypes) #查看每一列的类型
print(df['最大生命'].dtype) # 查看某一列的类型
print(df.isna()) #查看空值,返回bOOL值
print(df['最大生命'].isna)
print(df.isnull) #与isna()一样
print(df.columns) #查看列名
首先我们的head()以及tail命令也能查询出我们的结果,但是当我们需要具体的查询出一些内容的时候,我们需要加入一些条件,这里我们一共分为三种:
1、根据行和列的标签值索引进行查询 loc
查询1-6行的数据
按行查询时可以切片使用,这里叫行区间。与pytho有一定区别,1;6就是1-6行,按列查询时按照列名查询,这里也是列区间,[start,stop],start是自己规定的起点顺序,总之,.loc是按照行列标签进行查询,并且可以覆盖原值,推荐。
print(df.loc[1:6]) #按行查询时可以切片使用,这里叫行区间。与python有一定区别,1;6就是1-6行,
# 按列查询时按照列名查询,这里也是列区间,[start,stop],start是自己规定的起点顺序
# 总之,.loc是按照行列标签进行查询,并且可以覆盖原值,推荐。
查询1-6行的数据,只显示其中某一列或几列
# 这里相对于两个索引,第一个索引是行索引,这二个是列索引,
# 所以返回的是一个DateFrame,如果只有一个索引,则是Series,
# 查询的顺序是DateFrame->Series->值
print(df.loc[1:6,'最大生命']) #查询1-6行的数据,只显示‘最大生命这一列’
# 结果:
D:\python\envs\pythonProject\python.exe D:/python/project/数据分析/基础.py
1 7000
2 8341
3 8476
4 7344
5 8050
6 6164
# Name: 最大生命, dtype: int64
print(df.loc[1:5,'最大法力':'初始每5秒回血'])
这里相对于两个索引,第一个索引是行索引,这二个是列索引,
所以返回的是一个DateFrame,如果只有一个索引,则是Series,
查询的顺序是DateFrame->Series->值
#结果
# D:\python\envs\pythonProject\python.exe D:/python/project/数据分析/基础.py
最大法力 法力成长 初始法力 最高物攻 物攻成长 ... 物防成长 初始物防 最大每5秒回血 每5秒回血成长 初始每5秒回血
1 1760 95 430 318 11.000 ... 22.07 100 92 3.143 48
2 100 0 100 301 10.570 ... 27.07 125 115 4.143 57
3 1926 104 470 273 8.357 ... 20.36 109 117 4.214 58
4 0 0 0 343 12.360 ... 20.79 99 97 3.071 54
5 0 0 0 346 13.000 ... 21.57 98 106 3.643 55
[5 rows x 12 columns]
2、根据行和列的位置索引进行查询 .iloc
.iloc 与.loc的区别就在此,一个是标签值筛选查询,一个是位置索引筛选查询。
比如我们查询数据中1-3行,1-3列的数据
# .iloc 按照行列的位置查询
print(df.iloc[1:3,1:3])
# 结果:
# D:\python\envs\pythonProject\python.exe D:/python/project/数据分析/基础.py
生命成长 初始生命
1 275.0 3150
2 329.4 3450
3、根据布尔值进行查询
就是设置条件返回结果的布尔值,True Or False
print(df['最大生命']>10000)
# D:\python\envs\pythonProject\python.exe D:/python/project/数据分析/基础.py
0 False
1 False
2 False
3 False
4 False
...
逻辑运算 & (and) , ~(not) , |(or)
查询’最大生命'>5000且'攻击范围'=='近战’的数据
re = df[(df['最大生命']>5000) & (df['攻击范围'] == '近战')]
print(re.loc[:5,['最大生命','攻击范围']])
# D:\python\envs\pythonProject\python.exe D:/python/project/数据分析/基础.py
最大生命 攻击范围
0 7350 近战
1 7000 近战
2 8341 近战
3 8476 近战
4 7344 近战
5 8050 近战
同理,查询’最大生命'>5000或'攻击范围'=='近战’、查询’最大生命'>5000且'攻击范围'不等于'近战’
re = df[(df['最大生命']>5000) | (df['攻击范围'] == '近战')]
print(re.loc[:5,['最大生命','攻击范围']])
re = df[(df['最大生命']>5000) & ~(df['攻击范围'] == '近战')]
print(re.loc[:20,['最大生命','攻击范围']])
# D:\python\envs\pythonProject\python.exe D:/python/project/数据分析/基础.py
最大生命 攻击范围
6 6164 远程
19 5986 远程
20 5584 远程
注意!!!,我这里只查询了’最大生命'>5000且'攻击范围'不等于'近战’ 的数据,我们可以看到,我们明明筛选的是1-20行,却只查询出3行,这是因为每一行都有自己的一个索引,都有自己的定位,以至于返回的就是行的索引,所以我们在查询的时候一定要注意自己需要什么样的结果。
有时候我们的数据并不能直接拿来使用,比如我们的温度值,后面总是有摄氏度的单位。或如区分近战小兵和远程小兵,因为都是小兵,我们只用区分近战或远程就可,那么就可以替换掉小兵两个字。还有一种很常见的情况就是某个字段在不同的表中类型或者表述不同,为了将两张表联系起来我们也会将其中的两个相同意义的字段替换成相同的名字以及类型。这里我们常用的就是字符串的替换以及更改, str.replace()函数
这里我们将‘近战’替换为‘近’
# 替换
df.loc[:,'攻击范围'] = df['攻击范围'].str.replace('战','') #替换值,替换字符串的值是,str.replace(被替换值,更换后的值)
print(df.loc[:5,'攻击范围'])
# 结果:
# D:\python\envs\pythonProject\python.exe D:/python/project/数据分析/基础.py
0 近
1 近
2 近
3 近
4 近
5 近
# Name: 攻击范围, dtype: object
修改列名 rename()
df.rename(columns={'攻击范围':'近战或远程'},inplace=True)
print(df.loc[:5,'近战或远程'])
# D:\python\envs\pythonProject\python.exe D:/python/project/数据分析/基础.py
0 近战
1 近战
2 近战
3 近战
4 近战
5 近战
# Name: 近战或远程, dtype: object
修改某个值
# 修改某行某列的值
print(df.loc[5,'最大生命'])
df.loc[5,'最大生命'] = '5000'
print(df.loc[5,'最大生命'])
D:\python\envs\pythonProject\python.exe D:/python/project/数据分析/基础.py
8050
5000
我们在面对一个数据集的时候,首先要进行预处理,这也是以后机器学习的重要一步,第一步就是检查空值,处理空值。
df.fillna(value=1) #使用值为1填充所有的空值
df['最大生命'].fillna(df['生命成长'].max()) #最大生命列的空值用生命成长的最大值填充
df['最大生命'].fillna(df['生命成长'].min()) #最大生命列的空值用生命成长的最小值填充
df['最大生命'].fillna(df['生命成长'].mean()) #最大生命列的空值用生命成长的平均值填充
print(df.dropna()) #删除所有空值
df['最大生命'] = df['最大生命'].map(str.strip()) #清除空字符
df.rename(columns={'最大生命':'最高生命'}) #修改列名
df['最大生命'].astype(str) #修改列的类型
df['最大生命'].drop_duplicates(keep='first') #删除重复值,keep为位置参数
print(df['最大法力'].value_counts()) #统计最大法力各个值出现的次数
此外,还有求方差、平均值、相关系数等一些函数,感兴趣的同学可以多了解运用。
总结
今天主要讲解了pandas的一些基础以及一些基本运用,感兴趣的同学可以一起交流