Pandas之旅(一): 让我们把基础知识一次撸完,申精干货

为什么你需要pandas

大家好,今天想和大家分享一下有关pandas的学习新的,我因工作需要,从去年12月开始接触这个非常好用的包,到现在为止也是算是熟悉了一些,因此发现了它的强大之处,特意想要和朋友们分享,特别是如果你每天和excel打交道,总是需要编写一些vba函数或者对行列进行groupby啊,merge,join啊之类的,相信我,pandas会让你解脱的。

好啦,闲话少说,这篇文章的基础是假设你已经大概听说过了pandas的一些概念和用途,如果还大体上不太清楚的朋友们,可以去百度一下相关基础介绍,本分主要分成四个部分:

  1. 从Dataframe说起 : 简单了解Df这种数据结构,了解如何创建一个Df
  2. Dataframe基础操作 :基于行,列,index选取数据,新增数据,删除数据
  3. Pandas 读取 / 导出数据: 了解如何对excel,csv,tsv等常见文件进行读取并导出
  4. 总结: 精华部分,为大家总结一些非常实用的一些方法,并附带源码 ipynb以及py文件提供下载

1. 从Dataframe说起

首先,让我们明确一点,pandas这个包是在numpy的基础上得到的,因此可能有的朋友会有疑问,要不要先学学numpy,我的个人建议是真的不太需要,因为大多数的情况下基本用不到,当然,如果你处理的是科学实验类型的数据的话,当我没说,我这里的应用场景主要是一般类型的常见数据,比如:

  • 你是销售经理,经常需要汇总各地区的销售情况
  • 你在银行工作,不可避免的需要和数字,excel打交道
  • 你每天有很多重复的工作,比如备份,计算两表合并,分组,聚类等等。。。。。。

这种情况下,学习pandas会非常有用,这里我们说的数据都是二维的table,在pandas中也称作dataframe。
pandas中其实一共有三种类型的常见数据:

数据结构维度说明
Series1类似list,一维数组
Data Frames2最常见的二维数据结构,excel,sql的表就是这个
Panel3用的很少,三维结构

pandas主要包括三类数据结构,分别是:

Series:一维数组,与Numpy中的一维array类似。二者与Python基本的数据结构List也很相近,其区别是:List中的元素可以是不同的数据类型,而Array和Series中则只允许存储相同的数据类型,这样可以更有效的使用内存,提高运算效率。

DataFrame:二维的表格型数据结构。很多功能与R中的data.frame类似。可以将DataFrame理解为Series的容器。以下的内容主要以DataFrame为主。

Panel :三维的数组,可以理解为DataFrame的容器。

Pandas官网,更多功能请参考 http://pandas-docs.github.io/...

这里我们主要聚焦在Dataframe上,一个dataframe长的基本上如下这番模样:

NameAgeMark
John1578
Mike2386
Mary3695

我们把这个简单的dataframe起个名字叫df,那么它包括的最基础的元素有:

  • index:每行的索引,默认是从0开始,比如上面的df[0] 就是指 John 15 78这一行,依次类推,当然我们可以自己规定index,我以后会说
  • columns:列。这里就是指的是Name Age Mark 了
  • rows:行,df一共有3行

现在让我们看一个完整的图示:

clipboard.png

Dataframe 是应用最多也是最广泛的数据结构,现在就让我们开始学习创建一个dataframe吧~

1.1 创建Dataframe

创建一个Dataframe的方法有很多,总体上来说最常见的有及种:

  • 创建空dataframe
  • 利用dict创建
  • 从其他数据源读取(网站,excel,mysql等)

真实场景中大多数都是从其他数据源读取,我们会在第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

创建结果如下:

agecityname
018BeijingTom
130ShangHaiBob
225GuangZhouMary
340ShenZhenJames

很简单是不是,大家可能发现了,最左边的东西就是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
agecity
person
Tom18Beijing
Bob30ShangHai
Mary25GuangZhou
James40ShenZhen

这里的主要区别在于我们主动规定了‘name’列为索引。这种把一列默认为索引的方式在excel和sql里都有,异曲同工

从其他数据源读取(网站,excel,mysql等)

我会在第三部分介绍最常用的从excel,csv等读取数据

总体来说,有关创建Dataframe的部分我们不用了解太多,因为实际的场景基本不需要,都是直接从csv,tsv,sql,json等数据源直接获取。

2. Dataframe 基础操作

这里我们主要看一下基于索引,行,列,行和列的基础操作,最后会为大家总结一下,现在拿刚刚我们创建过的dataframe为例:

agecityname
018BeijingTom
130ShangHaiBob
225GuangZhouMary
340ShenZhenJames

2.1 对columns的基础操作

添加新列

添加一列非常简单:

df['country'] = 'USA'
df
agecitynamecountry
018BeijingTomUSA
130ShangHaiBobUSA
225GuangZhouMaryUSA
340ShenZhenJamesUSA
df['adress'] = df['country']
df
agecitynamecountryadress
018BeijingTomUSAUSA
130ShangHaiBobUSAUSA
225GuangZhouMaryUSAUSA
340ShenZhenJamesUSAUSA
修改列中的值

修改一个列的值也是很容易的,我们可以这样做:

df['country'] = 'China'
df
agecitynamecountryadress
018BeijingTomChinaUSA
130ShangHaiBobChinaUSA
225GuangZhouMaryChinaUSA
340ShenZhenJamesChinaUSA

或者稍微多想一步:


df['adress'] = df['city']+','+ df['country']
df
agecitynamecountryadress
018BeijingTomChinaBeijing,China
130ShangHaiBobChinaShangHai,China
225GuangZhouMaryChinaGuangZhou,China
340ShenZhenJamesChinaShenZhen,China
删除列

我们可以应用del或者drop函数,如果是drop,要注意传参时要加上axis = 1.这里简单和大家说明一下axis,这个东西其实就是指轴向,默认的axis=0,是纵向,axis=1是横向

df.drop('country',axis=1)
df
agecitynameadress
018BeijingTomBeijing,China
130ShangHaiBobShangHai,China
225GuangZhouMaryGuangZhou,China
340ShenZhenJamesShenZhen,China
del df['city']
df
agenameadress
018TomBeijing,China
130BobShangHai,China
225MaryGuangZhou,China
340JamesShenZhen,China

这里有一点大家需要注意:

  • drop和del的结果是基于df的两次单独操作,并不是连续的
  • 如果我们执行完drop后,重新查看df,这时你会发现df没有变化,因为没有真正的删除
  • 要想真正删除,需要加上关键字 inplace = True

因此如果我们想要连续删除country和city这两列,改进后的代码如下:

df.drop('country',axis=1, inplace=True)
del df['city']
df
agenameadress
018TomBeijing,China
130BobShangHai,China
225MaryGuangZhou,China
340JamesShenZhen,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']]
agename
018Tom
130Bob
225Mary
340James

这里注意,和选取单独一列不同,这里我们返回的类型是dataframe,之前的类型是series,我们可以这么理解,一列其实还是一维数组,但是两列及以上是二维的了,当然类型也变了

如果我们想要查看当前的所有列:

df.columns

Out:Index([u'age', u'name', u'adress'], dtype='object')

如果我们想要重新对列进行命名,基本有三种方法,大家挑一种自己喜欢的就行

  • 传递list
  • 传递dict
  • 传递 axis

用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

最后得到的效果是一样的:

AgeNameAdress
018TomBeijing,China
130BobShangHai,China
225MaryGuangZhou,China
340JamesShenZhen,China
根据条件给列赋值

我们现在想要根据人的年龄新增一列 Group,假设要求如下:

  • 18岁以下的是年轻人
  • 18-30的是中年人
  • 30以上的是老年人

我们有很多方法可以实现,先看一种,大家可以先忽视loc方法,这里传达的就是基础思路:

df['Group'] = 'elderly'
df.loc[df['Age']<=18, 'Group'] = 'young'
df.loc[(df['Age'] >18) & (df['Age'] <= 30), 'Group'] = 'middle_aged'
df
AgeNameAdressGroup
018TomBeijing,Chinayoung
130BobShangHai,Chinamiddle_aged
225MaryGuangZhou,Chinamiddle_aged
340JamesShenZhen,Chinaelderly

2.2 对 rows 的基础操作

loc函数 df.loc[row,column]

首先,大多数对于行的操作都可以通过loc函数实现,比如我们想要选取全部的行,除了直接打出df外,可以使用df.loc[:]

df.loc[:]
AgeNameAdressGroup
018TomBeijing,Chinayoung
130BobShangHai,Chinamiddle_aged
225MaryGuangZhou,Chinamiddle_aged
340JamesShenZhen,Chinaelderly
loc函数条件查询
df.loc[df['Age']>20]
NameAgeAdressGroup
1Bob30ShangHai,Chinamiddle_aged
2Mary25GuangZhou,Chinamiddle_aged
3James40ShenZhen,Chinaelderly
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
NameAgeAdressGroup
0NaNNaNNaNNaN
1Bob30.0ShangHai,Chinamiddle_aged
2NaNNaNNaNNaN
3James40.0ShenZhen,Chinaelderly
Query 筛选
# df.query('Age==30') 
df.query('Group=="middle_aged"'and 'Age>30' )
NameAgeAdressGroup
3James40ShenZhen,Chinaelderly

2.3 对 Dataframe 的基础了解

这里有很多有用的方法,可以帮助到大家大致了解数据的情况:


df.shape   # 了解行列情况
Out:(4, 4)

df.describe()   # 获取可计算列基础统计
Age
count4.000000
mean28.250000
std9.251126
min18.000000
25%23.250000
50%27.500000
75%32.500000
max40.000000
# df.head(3) #查看前三行数据,默认为5
df.tail(3)   #获得最后三行数据
NameAgeAdressGroup
1Bob30ShangHai,Chinamiddle_aged
2Mary25GuangZhou,Chinamiddle_aged
3James40ShenZhen,Chinaelderly

3. Pandas读取导出数据(csv)

Pandas 支持大部分常见数据文件读取与存储。一般清楚下,读取文件的方法以 pd.read_ 开头,而写入文件的方法以 pd.to_ 开头。这里我们开始熟悉一下最实用的对于csv文件的读取写入

写入CSV
df.to_csv('person.csv',index=None,sep=',')
import os
os.getcwd()
Out:  'C:\\Users\\E560'

这样大家就可以在'C:UsersE560'的路径下找到我们刚刚生成的csv文件了,这里我把index=None,舍弃了索引值

读取CSV

首先我们确认和python文件同一目录下存在我们刚刚导出的person.csv文件,之后可以很容易的读取了:

person = pd.read_csv('person.csv')
person
NameAgeAdressGroup
0Tom18Beijing,Chinayoung
1Bob30ShangHai,Chinamiddle_aged
2Mary25GuangZhou,Chinamiddle_aged
3James40ShenZhen,Chinaelderly

这时我们发现,即使我们读取的csv文件没有索引,但是pandas已经默认帮我们加上了

4. 总结,资料下载

好了,现在大家对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计算百分数变化
常见读取写入数据
数据类型读取写入
CSVread_csvto_csv
JSONread_jsonto_json
HTMLread_htmlto_html
EXCELread_excelto_excel
SQLread_sqlto_sql

好了,其实这些就是想要告诉大家如何学习pandas,没有必要了解每一个方法,但是现在想必你知道pandas能实现的功能很多,这样你有具体需求时只要详细查询一下文档即可,接下来几期我们会重点来看pandas里面对于df的各种操作,从简单的数据清理到类似于excel里面的vba,包括cancat,merge,join等等

下载

我把这一期的ipynb文件和py文件放到了GIthub上,大家如果想要下载可以点击下面的链接:

好啦,这一期就讲这么多,希望大家能够继续支持我,完结,撒花

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值