Py - Pandas笔记1


写在最前
Pandas是机器学习工作流程中,对数据进行预处理的重要工具。本笔记是同学在学习七月在线机器学习训练营二期中的<pandas花式数据统计与分析技能>时的投稿笔记,分为上下两篇。本笔记旨在记录并整理寒老师讲授的知识点,分享以供二期同学们交流及学习。



Pandas简介
1)Pandas是什么?
Pandas是Panel data and data analysis的简写,是一个专门用来数据处理和数据分析的Python工具库。
2)特点
基于numpy库
底层C实现,效率极高
对矩阵(高维数组)做计算
使用起来用在excel/R/SQL,快速入手
3)相关资源:
pandas官方网站《10 Minutes to pandas》
http://pandas.pydata.org/pandas-docs/stable/10min.html
寒老师推荐的pandas速查表,(学员)群文件共享下载

csv读写
比较简单,略过,更多选项查看pd.read_csv和pd.to_csv的帮助,如何分隔符,跳过多少行,头数,指定数据类型等。

Pandas的两种数据类型:
1)Series
一个series是一个一维的数据类型,其中每一个元素都有一个标签。series类似于Numpy中元素带标签的数组,或者Python中的字典。其中,标签可以是数字或者字符串。
理解为一个列
#导入相应库

import numpy as np
import pandas as pd

1.1 从列表初始化series[默认数字index]

my_list=[7,'Beijing','19',3.1415,-10000,'Happy']
series1=pd.Series(my_list)
#从列表初始化Series
series1[1]  #结果为'Beijing'
series1[1:4]  #Series这种数据类型默认用0到N这种格式做为索引index

b    Beijing
c        19
d     3.1415
dtype: object

什么是Pandas里的index呢?
可以理解为Python字典中的key,可以通过这个key访问对应的值。
那Series就可以想象成为一个KV对应的结构。

1.2 从列表初始化series,自己指定series的索引
my_list=[7,'Beijing','19',3.1415,-10000,'Happy']
series1=pd.Series(my_list, index=['a','b','c','d','e','f'])

从列表初始化Series,并自定义index

a          7
b    Beijing
c        19
d     3.1415
e     -10000
f      Happy
dtype: object
#使用自定义index访问Series
series1['a']
7
series1['f']
'Happy'

即使是自定义索引来初始化Series了,依旧可以通过数字来访问。

series1[1:4]
b    Beijing
c        19
d     3.1415
dtype: object

s1=pd.Series([1,2,3,4,5,6]
index=pd.date_range('20130101',periods=6))

带标签,标签是时间序列

s2=pd.Series(list('china! '))

不指定标签,系统自动是从0开始,

1.3 从字典初始化series
因为字典这种数据结构本身就是kv对应型的,因为可以直接用来构建series。index自动为字典的key

cities={'Beijing':55000,'Shanghai':60000,'Shenzhen':50000,
'Hangzhou':20000,'Guangzhou':45000,'Suzhou':None}
series3=pd.Series(cities)
series3
Beijing      55000.0
Guangzhou    45000.0
Hangzhou     20000.0
Shanghai     60000.0
Shenzhen     50000.0
Suzhou           NaN
dtype: float64

1.4 从numpy对象初始化series

series4=pd.Series(np.random.randn(5),index=[list('abcde')])
series4
a   -0.362932
b    1.670863
c   -0.665555
d    0.402865
e    1.789551
dtype: float64

2)DataFrame
一个DataFrame就是一张表格。Series可以理解为一维数组,DataFrame是一个二维数据,DataFrame是由多个Series组成的(可以理解为Series的集合)

2.1 从已有字典构建

population={'city':['Beijing','Shanghai','Guangzhou','Shenzhen',
            'Hangzhou','Chongqi'],'year':[2016,2017,2016,2017,2016,2016],
            'population':[2100,2300,1000,700,500,500]}
df1=pd.DataFrame(population)
df1
        city  population  year
0    Beijing        2100  2016
1   Shanghai        2300  2017
2  Guangzhou        1000  2016
3   Shenzhen         700  2017
4   Hangzhou         500  2016
5    Chongqi         500  2016

2.2 从list的字典中构建

l1=[{'JackMa':100000,'Han':80000,'David':10000},{'JackMa':9999999,'Han':90000}]
df3=pd.DataFrame(l1)
df3
     David    Han   JackMa
0  10000.0  80000   100000
1      NaN  90000  9999999

2.3 从已有Series构建

s1=pd.Series(list('china'))
s2=pd.Series(list('powers'))
df2=pd.DataFrame({'s1':s1,'s2':s2})
df2  #两个Series按index对齐(这里的index为默认的**0**至N),
      如果对应的index没有,则填为NaN*
    s1 s2
0    c  p
1    h  o
2    i  w
3    n  e
4    a  r
5  NaN  s

Index索引
理解index就是对应 每个行value的一个key。这样去理解简单些。
1)默认类型

population={'city':['Beijing','Shanghai','Guangzhou','Shenzhen',
            'Hangzhou','Chongqi'],'year':[2016,2017,2016,2017,2016,2016],
            'population':[2100,2300,1000,700,500,500]
}
df4.index  #查看索引
RangeIndex(start=0, stop=6, step=1)
df  默认索引均为从0开始,步长为1,总长为总行数减1的序列。

2)自定义索引并查看类型

pd.Index(list('china'))
Index(['c', 'h', 'i', 'n', 'a'], dtype='object')
type(pd.Index(list('china')))
<class 'pandas.core.indexes.base.Index'>

3)使用自定义索引

df4.index=list('china!')
df4  #可以看到这时的索引已经变**成指定的字母了
        city  population    year
c    Beijing        2100  2016.0
h   Shanghai        2300     NaN
i  Guangzhou        1000  2016.0
n   Shenzhen         700  2017.0
a   Hangzhou         500  2016.0
!    Chongqi         500  2016.0
df4.ix[['n','a'],[0,1]]    #正常使用并访问
       city  population
n  Shenzhen         700
a  Hangzhou         500

4)多层index

series6=pd.Series(np.random.randn(10),
    index=[['a','a','a','b','b','c','c','d','d','d'],[1,2,3,1,2,1,2,1,2,3]])
series6.index
MultiIndex(levels=[['a', 'b', 'c', 'd'], [1, 2, 3]],
    labels=[[0, 0, 0, 1, 1, 2, 2, 3, 3, 3], [0, 1, 2, 0, 1, 0, 1, 0, 1, 2]]) 
多层index的访问
series6['b':'c']
b  1    0.198059
   2    0.418935
c  1   -0.146183
   2    0.134893
dtype: float64
series6[:2]
a  1    0.898547
   2    0.132076
dtype: float64

5)unstack
series6
a  1    0.898547
   2    0.132076
   3   -0.911465
b  1    0.198059
   2    0.418935
c  1   -0.146183
   2    0.134893
d  1    0.925714
   2    0.657029
   3   -0.237139
dtype: float64
series6.unstack()
          1         2         3
a  0.898547  0.132076 -0.911465
b  0.198059  0.418935       NaN
c -0.146183  0.134893       NaN
d  0.925714  0.657029 -0.237139
type(series6.unstack())  #unstack一个Series后,变为DataFrame了。
<class 'pandas.core.frame.DataFrame'>

寒老师:千万不要因为pandas功能强大就给自己挖坑,开始的时候就老老实实地用二维表格,或者把多维表格降为二维。


Series和DataFrame的操作
可以把series理解为一列,dataframe可以理解为由很多个列(series)构成的列。
我们可以像对待一个list一样series,完成各类操作

cities={'Beijing':55000,'Shanghai':60000,'Shenzhen':50000,'Hangzhou':20000,
        'Guangzhou':45000,'Suzhou':None }
series5=pd.Series(cities**,name=**'incomes')

1)DataFrame描述性命令

info()  #了解dataframe整体结构,列,数据类型
describe()    #了解数据分布
head()
tail()

2)访问
2.1 Series切片访问

series5[:5]
Beijing      55000.0
Guangzhou    45000.0
Hangzhou     20000.0
Shanghai     60000.0
Shenzhen     50000.0
Name: incomes, dtype: object

2.2 指定索引访问,注意这里位置可以任意调换

series5[[0,4,3,1,2]]
Beijing      55000.0
Shenzhen     50000.0
Shanghai     60000.0
Guangzhou    45000.0
Hangzhou     20000.0
Name: incomes, dtype: object
series5[['Shanghai','Suzhou']]
Shanghai    60000.0
Suzhou          NaN
dtype: float64

3)元素检查
3.1 in关键字,类似于检查元素是否在列表中一样的操作

'Suzhou' in series5
True
'Nanjing' in series5
False

3.2 Get方法访问,如果指定的index不存在,则返回nan

series5.get('Suzhou')
nan
series5.get('Beijing')
55000.0

4)条件boolean indexing

conditions=(series5==60000)
conditions
Beijing      False
Guangzhou    False
Hangzhou     False
Shanghai      True
Shenzhen     False
Suzhou       False
Name: incomes, dtype: object

按条件进行对series过滤后,会得到一个boolean型变量组成的Series对象,叫做boolean**** indexing。这个series可以传递作为条件,过滤掉所有相应位置为False的记录,得到最终结果。

series5[conditions]
Shanghai    60000.0
Name: incomes, dtype: object

4.1 非空与非空值过滤
找出所有的空值 或 非空值 的 boolean indexing****#bool****条件

series5.notnull()  #或-series5.isnull()
Beijing       True
Guangzhou     True
Hangzhou      True
Shanghai      True
Shenzhen      True
Suzhou       False
Name: incomes, dtype: bool
series5.isnull()  #或-series5.notnull()
Beijing      False
Guangzhou    False
Hangzhou     False
Shanghai     False
Shenzhen     False
Suzhou        True

5)简单数学运算
5.1 求均值,中位数,最大最小,

series5.mean()
46000.0
series5.median()
50000.0
series5[series5.isnull]=series5.mean()
#把空项填充为均值

6)元素赋值
6.1 指定Series的index赋值

series5['Shenzhen']=70000
series5['Shenzhen']
70000

6.2 按boolean indexing条件过滤后赋值

series5[series5<50000]=50001
series5
Beijing      55000.0
Guangzhou    50001.0
Hangzhou     50001.0
Shanghai     60000.0
Shenzhen     50000.0
Suzhou           NaN
Name: incomes, dtype: float64

7)数学运算
series5 0.5# 算开方,列表可不支持这样的操作,这也是pandas强大的地方

Beijing      234.520788
Guangzhou    223.609034
Hangzhou     223.609034
Shanghai     244.948974
Shenzhen     223.606798
Suzhou              NaN
Name: incomes, dtype: float64

np.log(series5)
Beijing      10.915088
Guangzhou    10.819798
Hangzhou     10.819798
Shanghai     11.002100
Shenzhen     10.819778
Suzhou             NaN
Name: incomes, dtype: float64

7.1 运算->自动indexing对齐
Pandas有个强大的功能,叫做对齐。我们新建两个series,列的顺序是不是对齐的,而且两个series中都有另一个series中没有项,但依旧可以进行运算,结果为NaN

s1=pd.Series({'Beijing':55000,'Shanghai':60000,'Hangzhou':20000})
s2=pd.Series({'Shenzhen':50000,'Beijing':55000,'Shanghai':60000})
s1
Beijing     55000
Hangzhou    20000
Shanghai    60000
dtype: int64
s2
Beijing     55000
Shanghai    60000
Shenzhen    50000
dtype: int64
s1+s2
Beijing     110000.0
Hangzhou         NaN
Shanghai    120000.0
Shenzhen         NaN
dtype: float64

总结:pa****ndas****自动对齐两个series的index,进行运算。


更多访问方式
1)loc
按indx取出Series,通过行标签索引行数据,有标签时可以通过标签没标签时可以通过行号。

df4.loc[0:2]
city  population  year  bonus   average
0    Beijing        2100  2016   6666  3.174286
1   Shanghai        2300  2017   6666  2.898261
2  Guangzhou        1000  2016   6666  6.666000
df4.loc[[0,3],['city','average']]
# 前边 [0,3]代表选行,[‘city’,’average’]代表选列
       city   average
0   Beijing  3.174286
3  Shenzhen  9.522857
df4.loc[df4.average>10,['city','average']]
#前边代表按列条件去过滤后剩下的行,['city', 'average']代表选列

2)iloc
只能通过数字索引获来取数据

df4.iloc[1:,1:]
   population    year
1        2300     NaN
2        1000  2016.0
3         700  2017.0
4         500  2016.0
5         500  2016.0

3)Ix
混合索引,可以和标签,索引,行号混用。

*df4.ix[:4,['city','population']]*
        city  population
0    Beijing        2100
1   Shanghai        2300
2  Guangzhou        1000
3   Shenzhen         700
4   Hangzhou         500

4)条件组合与判断访问
4.1 条件组合

 (df4.population==2100)|(df4.population==1000)
0     True
1    False
2     True
3    False
4    False
5    False
df4.loc[((df4.population==2100)|(df4.population==1000)),:]
        city  population  year
0    Beijing        2100  2016
2  Guangzhou        1000  2016

4.2 指定条件

df4.population.isin([2100,1000])
0     True
1    False
2     True
3    False
4    False
5    False

可以看到,使用isin函数得到的是一个boolean indexing
Pandas里的条件否定,可以简单前边加一个负号即可。

df4.population.isin([2100,1000])
0    False
1     True
2    False
3     True
4     True
5     True
Name: population, dtype: bool
 
df4.loc[df4.population.isin([2100,1000]),:]
# isin 的传入参数可以是一个列表,ndarray,Series
        city  population  year
0    Beijing        2100  2016
2  Guangzhou        1000  2016

5)缺省值与缺少值填充
缺少值的类型是numpy中的nan

df4.iloc[1,2]=np.nan
        city  population    year
0    Beijing        2100  2016.0
1   Shanghai        2300     NaN
2  Guangzhou        1000  2016.0
3   Shenzhen         700  2017.0
4   Hangzhou         500  2016.0
5    Chongqi         500  2016.0
 
df4.fillna(2017)
#注意此时是返回一个修过的df,而原来的df不会被修改
如果要修改原来的df,指定inplace=True*
        city  population    year
0    Beijing        2100  2016.0
1   Shanghai        2300  2017.0
2  Guangzhou        1000  2016.0
3   Shenzhen         700  2017.0
4   Hangzhou         500  2016.0
5    Chongqi         500  2016.0

高级填充
如果是像天气,股票价格的取样周期很短,如每半分钟一次的的数据,缺少值就适合用这种方法填充。但同样的场景,每半小时取样,就不适用这种方法了。先分析场景很重要。

df4.fillna(method='ffill') #按空值前一值填充
df4.fillna(method='bfill') #按空值后一值填充

广播特性Broadcasting

df4=pd.DataFrame(population)
df4['bonus']=6666 
df4#这里的6666为标量,要应用到整个series,,就会使用到广播
df4
        city  population  year  bonus
0    Beijing        2100  2016   6666
1   Shanghai        2300  2017   6666
2  Guangzhou        1000  2016   6666
3   Shenzhen         700  2017   6666
4   Hangzhou         500  2016   6666
5    Chongqi         500  2016   6666

并行进行的广播,非循环

df4['average']=df4['bonus']/df4['population']
df4
        city  population  year  bonus    average
0    Beijing        2100  2016   6666   3.174286
1   Shanghai        2300  2017   6666   2.898261
2  Guangzhou        1000  2016   6666   6.666000
3   Shenzhen         700  2017   6666   9.522857
4   Hangzhou         500  2016   6666  13.332000
5    Chongqi         500  2016   6666  13.332000

简单绘画

from matplotlib import pyplot as plt
df4.population.plot(kind='bar')
matplotlib.axes._subplots.AxesSubplot object at 0x0000012F67F09E80
plt.show()

写在最后
本篇笔记偏Pandas基础入门及介绍,课后留的作业要远比笔记涉及的多,要难。在第二篇笔记中将记录这些Pandas高级应用,将在公众号上整理发布,同学们敬请期待。

python笔记:
Python数据分析之:numpy入门(一)
Python数据分析之:numpy入门(二)
Python数据分析之:numpy入门(三)
Python数据分析之:numpy入门(四)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,529评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,015评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,409评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,385评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,387评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,466评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,880评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,528评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,727评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,528评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,602评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,302评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,873评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,890评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,132评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,777评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,310评论 2 342

推荐阅读更多精彩内容