你们好,今天想和你们分享一下有关pandas的学习新的,我因工做须要,从去年12月开始接触这个很是好用的包,到如今为止也是算是熟悉了一些,所以发现了它的强大之处,特地想要和朋友们分享,特别是若是你天天和excel打交道,老是须要编写一些vba函数或者对行列进行groupby啊,merge,join啊之类的,相信我,pandas会让你解脱的。html
好啦,闲话少说,这篇文章的基础是假设你已经大概据说过了pandas的一些概念和用途,若是还大致上不太清楚的朋友们,能够去百度一下相关基础介绍,本分主要分红四个部分:python
首先,让咱们明确一点,pandas这个包是在numpy的基础上获得的,所以可能有的朋友会有疑问,要不要先学学numpy,个人我的建议是真的不太须要,由于大多数的状况下基本用不到,固然,若是你处理的是科学实验类型的数据的话,当我没说,我这里的应用场景主要是通常类型的常见数据,好比:mysql
这种状况下,学习pandas会很是有用,这里咱们说的数据都是二维的table,在pandas中也称做dataframe。 pandas中其实一共有三种类型的常见数据:git
数据结构 | 维度 | 说明 |
---|---|---|
Series | 1 | 相似list,一维数组 |
Data Frames | 2 | 最多见的二维数据结构,excel,sql的表就是这个 |
Panel | 3 | 用的不多,三维结构 |
pandas主要包括三类数据结构,分别是:github
Series:一维数组,与Numpy中的一维array相似。两者与Python基本的数据结构List也很相近,其区别是:List中的元素能够是不一样的数据类型,而Array和Series中则只容许存储相同的数据类型,这样能够更有效的使用内存,提升运算效率。sql
DataFrame:二维的表格型数据结构。不少功能与R中的data.frame相似。能够将DataFrame理解为Series的容器。如下的内容主要以DataFrame为主。json
Panel :三维的数组,能够理解为DataFrame的容器。api
Pandas官网,更多功能请参考 pandas-docs.github.io/pandas-docs…数组
这里咱们主要聚焦在Dataframe上,一个dataframe长的基本上以下这番模样:bash
Name | Age | Mark |
---|---|---|
John | 15 | 78 |
Mike | 23 | 86 |
Mary | 36 | 95 |
咱们把这个简单的dataframe起个名字叫df,那么它包括的最基础的元素有:
Dataframe 是应用最多也是最普遍的数据结构,如今就让咱们开始学习建立一个dataframe吧~ ###1.1 建立Dataframe###
建立一个Dataframe的方法有不少,整体上来讲最多见的有及种:
真实场景中大多数都是从其余数据源读取,咱们会在第3部分讲到
建立空dataframe
这个很是简单:
import pandas as pd
# Calling DataFrame constructor
df = pd.DataFrame()
print(df)
Out:Empty DataFrame
Columns: []
Index: []
复制代码
利用dict建立(1)
import pandas as pd
print (f" Using {pd.__name__},Version {pd.__version__}")
Out: Using pandas , version 0.23.4
复制代码
首先要import pandas 包,这里缩写为pd,如今让咱们从dict建立一个dataframe:
>>> dict = {'name':["Tom", "Bob", "Mary", "James"],
'age': [18, 30, 25, 40],
'city':["Beijing", "ShangHai","GuangZhou", "ShenZhen"]}
>>> df = pd.DataFrame(dict)
>>> df
复制代码
建立结果以下:
age | city | name | |
---|---|---|---|
0 | 18 | Beijing | Tom |
1 | 30 | ShangHai | Bob |
2 | 25 | GuangZhou | Mary |
3 | 40 | ShenZhen | James |
很简单是否是,你们可能发现了,最左边的东西就是index ,0,1,2,3,若是咱们不指定会自动生成从0默认开始的序列,一直到你的dataframe的最后一行,相似于excel左边的编号
利用dict建立(2)
此次让咱们建立的更加规范一些:
index = pd.Index(["Tom", "Bob", "Mary", "James"],name = 'person')
cols = ['age','city']
data = [[18,'Beijing'],
[30,'ShangHai'],
[25,'GuangZhou'],
[40,'ShenZhen']]
df =pd.DataFrame(index = index,data =data,columns = cols)
df
复制代码
age | city | |
---|---|---|
person | ||
Tom | 18 | Beijing |
Bob | 30 | ShangHai |
Mary | 25 | GuangZhou |
James | 40 | ShenZhen |
这里的主要区别在于咱们主动规定了‘name’列为索引。这种把一列默认为索引的方式在excel和sql里都有,殊途同归
从其余数据源读取(网站,excel,mysql等)
我会在第三部分介绍最经常使用的从excel,csv等读取数据
整体来讲,有关建立Dataframe的部分咱们不用了解太多,由于实际的场景基本不须要,都是直接从csv,tsv,sql,json等数据源直接获取。
这里咱们主要看一下基于索引,行,列,行和列的基础操做,最后会为你们总结一下,如今拿刚刚咱们建立过的dataframe为例:
age | city | name | |
---|---|---|---|
0 | 18 | Beijing | Tom |
1 | 30 | ShangHai | Bob |
2 | 25 | GuangZhou | Mary |
3 | 40 | ShenZhen | James |
添加新列
添加一列很是简单:
df['country'] = 'USA'
df
复制代码
age | city | name | country | |
---|---|---|---|---|
0 | 18 | Beijing | Tom | USA |
1 | 30 | ShangHai | Bob | USA |
2 | 25 | GuangZhou | Mary | USA |
3 | 40 | ShenZhen | James | USA |
df['adress'] = df['country']
df
复制代码
age | city | name | country | adress | |
---|---|---|---|---|---|
0 | 18 | Beijing | Tom | USA | USA |
1 | 30 | ShangHai | Bob | USA | USA |
2 | 25 | GuangZhou | Mary | USA | USA |
3 | 40 | ShenZhen | James | USA | USA |
修改列中的值
修改一个列的值也是很容易的,咱们能够这样作:
df['country'] = 'China'
df
复制代码
age | city | name | country | adress | |
---|---|---|---|---|---|
0 | 18 | Beijing | Tom | China | USA |
1 | 30 | ShangHai | Bob | China | USA |
2 | 25 | GuangZhou | Mary | China | USA |
3 | 40 | ShenZhen | James | China | USA |
或者稍微多想一步:
df['adress'] = df['city']+','+ df['country']
df
复制代码
age | city | name | country | adress | |
---|---|---|---|---|---|
0 | 18 | Beijing | Tom | China | Beijing,China |
1 | 30 | ShangHai | Bob | China | ShangHai,China |
2 | 25 | GuangZhou | Mary | China | GuangZhou,China |
3 | 40 | ShenZhen | James | China | ShenZhen,China |
删除列
咱们能够应用del或者drop函数,若是是drop,要注意传参时要加上axis = 1.这里简单和你们说明一下axis,这个东西其实就是指轴向,默认的axis=0,是纵向,axis=1是横向
df.drop('country',axis=1)
df
复制代码
age | city | name | adress | |
---|---|---|---|---|
0 | 18 | Beijing | Tom | Beijing,China |
1 | 30 | ShangHai | Bob | ShangHai,China |
2 | 25 | GuangZhou | Mary | GuangZhou,China |
3 | 40 | ShenZhen | James | ShenZhen,China |
del df['city']
df
复制代码
age | name | adress | |
---|---|---|---|
0 | 18 | Tom | Beijing,China |
1 | 30 | Bob | ShangHai,China |
2 | 25 | Mary | GuangZhou,China |
3 | 40 | James | ShenZhen,China |
这里有一点你们须要注意:
所以若是咱们想要连续删除country和city这两列,改进后的代码以下:
df.drop('country',axis=1, inplace=True)
del df['city']
df
复制代码
age | name | adress | |
---|---|---|---|
0 | 18 | Tom | Beijing,China |
1 | 30 | Bob | ShangHai,China |
2 | 25 | Mary | GuangZhou,China |
3 | 40 | James | ShenZhen,China |
选取列
这个很是简单,实现代码以下:
df['age'] # 选取age这一列
0 18
1 30
2 25
3 40
Name: age, dtype: int64
复制代码
或者这样:
df.name
复制代码
0 Tom
1 Bob
2 Mary
3 James
Name: name, dtype: object
复制代码
若是想要选取多个列也很容易,传递一个list就行啦:
df[['age','name']]
复制代码
age | name | |
---|---|---|
0 | 18 | Tom |
1 | 30 | Bob |
2 | 25 | Mary |
3 | 40 | James |
这里注意,和选取单独一列不一样,这里咱们返回的类型是dataframe,以前的类型是series,咱们能够这么理解,一列其实仍是一维数组,可是两列及以上是二维的了,固然类型也变了
若是咱们想要查看当前的全部列:
df.columns
Out:Index([u'age', u'name', u'adress'], dtype='object')
复制代码
若是咱们想要从新对列进行命名,基本有三种方法,你们挑一种本身喜欢的就行
用list:
df.columns = ['Age','Name','Adress']
df
复制代码
用dict:
df.rename(index = str, columns = {'age':'Age','name':'Name','adress':'Adress'}) #这里index=str 有没有都行,我这么作是为了规范
df
复制代码
用axis:
df.rename(str.capitalize, axis='columns',inplace =True)
df
复制代码
最后获得的效果是同样的:
Age | Name | Adress | |
---|---|---|---|
0 | 18 | Tom | Beijing,China |
1 | 30 | Bob | ShangHai,China |
2 | 25 | Mary | GuangZhou,China |
3 | 40 | James | ShenZhen,China |
根据条件给列赋值
咱们如今想要根据人的年龄新增一列 Group,假设要求以下:
咱们有不少方法能够实现,先看一种,你们能够先忽视loc方法,这里传达的就是基础思路:
df['Group'] = 'elderly'
df.loc[df['Age']<=18, 'Group'] = 'young'
df.loc[(df['Age'] >18) & (df['Age'] <= 30), 'Group'] = 'middle_aged'
df
复制代码
Age | Name | Adress | Group | |
---|---|---|---|---|
0 | 18 | Tom | Beijing,China | young |
1 | 30 | Bob | ShangHai,China | middle_aged |
2 | 25 | Mary | GuangZhou,China | middle_aged |
3 | 40 | James | ShenZhen,China | elderly |
loc函数 df.loc[row,column]
首先,大多数对于行的操做均可以经过loc函数实现,好比咱们想要选取所有的行,除了直接打出df外,可使用df.loc[:]
df.loc[:]
复制代码
Age | Name | Adress | Group | |
---|---|---|---|---|
0 | 18 | Tom | Beijing,China | young |
1 | 30 | Bob | ShangHai,China | middle_aged |
2 | 25 | Mary | GuangZhou,China | middle_aged |
3 | 40 | James | ShenZhen,China | elderly |
loc函数条件查询
df.loc[df['Age']>20]
复制代码
Name | Age | Adress | Group | |
---|---|---|---|---|
1 | Bob | 30 | ShangHai,China | middle_aged |
2 | Mary | 25 | GuangZhou,China | middle_aged |
3 | James | 40 | ShenZhen,China | elderly |
loc函数条件行列查询
df.loc[df['Group']=='middle_aged','Name']
1 Bob
2 Mary
Name: Name, dtype: object
复制代码
Where 查询
filter_adult = df['Age']>25
result = df.where(filter_adult)
result
复制代码
Name | Age | Adress | Group | |
---|---|---|---|---|
0 | NaN | NaN | NaN | NaN |
1 | Bob | 30.0 | ShangHai,China | middle_aged |
2 | NaN | NaN | NaN | NaN |
3 | James | 40.0 | ShenZhen,China | elderly |
Query 筛选
# df.query('Age==30')
df.query('Group=="middle_aged"'and 'Age>30' )
复制代码
Name | Age | Adress | Group | |
---|---|---|---|---|
3 | James | 40 | ShenZhen,China | elderly |
这里有不少有用的方法,能够帮助到你们大体了解数据的状况:
df.shape # 了解行列状况
Out:(4, 4)
复制代码
df.describe() # 获取可计算列基础统计
复制代码
Age | |
---|---|
count | 4.000000 |
mean | 28.250000 |
std | 9.251126 |
min | 18.000000 |
25% | 23.250000 |
50% | 27.500000 |
75% | 32.500000 |
max | 40.000000 |
# df.head(3) #查看前三行数据,默认为5
df.tail(3) #得到最后三行数据
复制代码
Name | Age | Adress | Group | |
---|---|---|---|---|
1 | Bob | 30 | ShangHai,China | middle_aged |
2 | Mary | 25 | GuangZhou,China | middle_aged |
3 | James | 40 | ShenZhen,China | elderly |
Pandas 支持大部分常见数据文件读取与存储。通常清楚下,读取文件的方法以 pd.read_ 开头,而写入文件的方法以 pd.to_ 开头。这里咱们开始熟悉一下最实用的对于csv文件的读取写入
写入CSV
df.to_csv('person.csv',index=None,sep=',')
复制代码
import os
os.getcwd()
Out: 'C:\\Users\\E560'
复制代码
这样你们就能够在'C:\Users\E560'的路径下找到咱们刚刚生成的csv文件了,这里我把index=None,舍弃了索引值
读取CSV
首先咱们确认和python文件同一目录下存在咱们刚刚导出的person.csv文件,以后能够很容易的读取了:
person = pd.read_csv('person.csv')
person
复制代码
Name | Age | Adress | Group | |
---|---|---|---|---|
0 | Tom | 18 | Beijing,China | young |
1 | Bob | 30 | ShangHai,China | middle_aged |
2 | Mary | 25 | GuangZhou,China | middle_aged |
3 | James | 40 | ShenZhen,China | elderly |
这时咱们发现,即便咱们读取的csv文件没有索引,可是pandas已经默认帮咱们加上了
好了,如今你们对pandas的使用已经有了基础的印象,我给你们简单总结一下经常使用的方法:
使用标签选取数据
df.loc[行标签,列标签]
df.loc['Tom':'Mary'] #选取 Tom至Mary的全部行的数据,Tom和Mary是index
df.loc[:,'city'] #选取 city 列的数据
复制代码
df.loc 的第一个参数是行标签,第二个参数为列标签(可选参数,默认为全部列标签),两个参数既能够是列表也能够是单个字符,若是两个参数都为列表则返回的是 DataFrame,不然,则为 Series。
PS:loc为location的缩写。
使用位置(index)选取数据
df.iloc[行位置,列位置]
df.iloc[1,1] #选取第二行,第二列的值,返回的为单个值
df.iloc[[0,2],:] #选取第一行及第三行的数据
df.iloc[0:2,:] #选取第一行到第三行(不包含)的数据
df.iloc[:,1] #选取全部记录的第二列的值,返回的为一个Series
df.iloc[1,:] #选取第一行数据,返回的为一个Series
复制代码
PS:iloc 则为 integer & location 的缩写
经过逻辑指针进行数据切片
df[逻辑条件]
df[df.age >= 18] #单个逻辑条件
df[(df.age >=18 ) & (df.country=='China') ] #多个逻辑条件组合
复制代码
了解并掌握数据大体状况
方法 | 解释 |
---|---|
count | 非na值的数量 |
describe | 针对Series或个DataFrame列计算汇总统计 |
min、max | 计算最小值和最大值 |
argmin、argmax | 计算可以获取到最大值和最小值得索引位置(整数) |
idxmin、idxmax | 计算可以获取到最大值和最小值得索引值 |
quantile | 计算样本的分位数(0到1) |
sum | 值的总和 |
mean | 值得平均数 |
median | 值得算术中位数(50%分位数) |
mad | 根据平均值计算平均绝对离差 |
var | 样本值的方差 |
std | 样本值的标准差 |
skew | 样本值得偏度(三阶矩) |
kurt | 样本值得峰度(四阶矩) |
cumsum | 样本值得累计和 |
cummin,cummax | 样本值得累计最大值和累计最小值 |
cumprod | 样本值得累计积 |
diff | 计算一阶差分(对时间序列颇有用) |
pct_change | 计算百分数变化 |
常见读取写入数据
数据类型 | 读取 | 写入 |
---|---|---|
CSV | read_csv | to_csv |
JSON | read_json | to_json |
HTML | read_html | to_html |
EXCEL | read_excel | to_excel |
SQL | read_sql | to_sql |
好了,其实这些就是想要告诉你们如何学习pandas,没有必要了解每个方法,可是如今想必你知道pandas能实现的功能不少,这样你有具体需求时只要详细查询一下文档便可,接下来几期咱们会重点来看pandas里面对于df的各类操做,从简单的数据清理到相似于excel里面的vba,包括cancat,merge,join等等
下载
我把这一期的ipynb文件和py文件放到了GIthub上,你们若是想要下载能够点击下面的连接: