Pandas_part01
1 pandas简介
1.1 前置课程numpy与scipy
numpy与scipy通常用于处理规范的数据,对于缺失值、数据的类型要求非常严格,然而实际情况下,原始数据通常不是很规范,且存在缺失值,或者数据类型混乱的情况,此时numpy和scipy将不再适用。
1.2 pandas的应用
Pandas最初被作为金融数据分析工具而开发出来,因此,pandas为时间序列分析提供了很好的支持。 Pandas的名称来自于面板数据(panel data)和python数据分析(data analysis)。panel data是经济学中关于多维数据集的一个术语,在Pandas中基本数据结构主要有Series和DataFrame两种,另外,也提供了 panel的数据类型。
2 pandas基本数据结构 - Series
所有代码默认导入以下模块
from pandas import Series,DataFrame
import numpy as np
2.1 创建Series数据
2.1.1 通过列表创建
不指定索引,默认生成0,1,2索引
series1=Series([‘小明’,‘小红’,‘小花’])
series1
通过index=[indeies]的方式指定索引
series2=Series([‘小明’,‘小红’,‘小花’],index=[‘a’,‘b’,‘c’])
series2
a 小明
b 小红
c 小花
dtype: object
2.1.2 通过ndarray创建
series2=Series(np.arange(3))
series20 0
1 1
2 2
dtype: int32
2.2 DataFrame数据创建
2.2.1 通过字典创建
pop={‘省份’:[‘上海’,‘江苏’,‘浙江’],
‘年份’:[‘2017’,‘2016’,‘2015’],
‘人数’:[‘0.8’,‘1.2’,‘1.1’]}
df=DataFrame(pop)
df
image_1cgggd6h0egrrma1pm71u391u882q.png-5.4kB
2.2.2 通过字典套字典创建
province={‘上海’:{2000:0.7,2001:0.68,2002:0.8,},
‘江苏’:{2000:0.2,2001:0.35,2002:0.34,}}
df2=DataFrame(province)
df2
image_1cgggeqhb18u61oa1ra1cc419gl3n.png-4.6kB
2.3 DataFrame数据常用属性
.T – df的行列转置
.col_name – 获取列数据
.index – 获取df的行索引
.columns – 获取df的列索引
3 pandas快速进阶 - 索引与切片
3.1 Series数据
3.1.1 索引切片
series=Series(np.arange(4),index=[‘a’,‘b’,‘c’,‘d’])
series
image_1cggdqtpr8r670gu4s1i9e9ni3n.png-2.3kB
series[1]
series[‘b’]
1
series[[‘a’,‘b’,‘c’]]
series[‘a’:‘c’] # 字符串切片索引区间为闭区间
image_1cggdssk01kf9es317ga1d5a13nj44.png-2kB
3.1.1 花式索引(条件)切片
series[series<2]
mask = series<2 # 花式索引
series[mask]
image_1cggdu2u1suc1kbpduo13mur9f4h.png-1.7kB
3.2 DataFrame数据
pop={‘省份’:[‘上海’,‘江苏’,‘浙江’],
‘年份’:[‘2017’,‘2016’,‘2015’],
‘人数’:[‘0.8’,‘1.2’,‘1.1’]}
df=DataFrame(pop)
df
image_1cggitvslcvf1rc622bksj7bic5.png-5.2kB
3.2.1 行切片
df[0:2]
image_1cggivbod5u71ebe3hs1e6bcshd2.png-3.9kB
3.2.2 列切片
df[[‘人数’,‘省份’]]
image_1cggj29fpp57f7m14b5a1ab3qdf.png-4.4kB
3.2.3 .loc[mask] – 花式索引定位
df.loc[df[‘人数’].astype(float)<=1] # 获取一行
image_1cggjbsdu1ih01qna7u4p9v74ds.png-3kB
4 pandas快速进阶 - 数据运算
4.1 Series数据相加
s1=Series([1,2,3,1],index=[‘a’,‘c’,‘d’,‘e’])
s2=Series([12,42,23,12,45],index=[‘a’,‘c’,‘e’,‘f’,‘g’])
s1+s2
a 13.0
c 44.0
d NaN
e 24.0
f NaN
g NaN
dtype: float64
4.2 DataFrame数据相加
df1=DataFrame(np.arange(12).reshape((3,4)),columns=list(‘abcd’))
df2=DataFrame(np.arange(20).reshape((4,5)),columns=list(‘abcde’))
df1+df2
image_1cggd23g717r42eqs6ai9q63p.png-6.2kB
df1.add(df2,fill_value=0) # 将df1的缺少的行全部补充为0
image_1cggd2h5d193r15d91ceuikg16mf16.png-5.8kB
df1.add(df2).fillna(0)
image_1cggd2rftv3f21h3aa1t0crps1j.png-5.2kB
4.3 DataFrame数据与Series数据运算
df3=DataFrame(np.arange(12).reshape((4,3)),columns=list(‘abc’),index=[‘北京’,‘上海’,‘天津’,‘重庆’])
df3
series=df3.loc[‘北京’]
series
image_1cggdn7rn2kr643n9l14c41e2r2g.png-4.6kB
image_1cggdnisb1qq9u4b3jllbfmgq2t.png-3.1kB
df3-series
image_1cggdo6v11a7dqn91l4m1g2an5m3a.png-3.7kB
5 pandas快速进阶 - 函数应用和映射df.apply()
5.1 numpy中常用函数
df=DataFrame(np.random.randn(4,3),columns=list(‘bde’),
index=[‘one’,‘two’,‘three’,‘four’])
df
image_1cggebflf185uk7c1g0e1dlld4s4u.png-10.1kB
np.abs(df) # 操作视图,原数据不变
image_1cggeckfo1asv1c7dod3i3st15b.png-10.1kB
5.2 自定义函数
5.2.1 apply()
求每一列的最大值和最小值之差
f=lambda x:x.max()-x.min()
df.apply(f) # 对整行或整列进行操作
image_1cggee9tg164d183r1q01id6ke068.png-3.6kB
df.apply(f,axis=1)
image_1cggeesgt1jjeds71vmc16arkt06l.png-4.7kB
5.2.2 applymap()
f2 = lambda x:’%.2f’%x
对DataFrame中的每一个元素使用函数映射
df.applymap(f2) # 对df中每一个元素进行操作
image_1cggfj7gafu2v32jt61fsc1b0h9.png-6.4kB
5.2.3 Series.map()
df[‘e’].map(f2)
image_1cggfu6m217cp15cq13s71fp91hs7m.png-4.6kB
6 pandas快速进阶 - 索引排序
6.1 行索引排序(默认)
df=DataFrame(np.arange(8).reshape((2,4)),index=[‘three’,‘one’],
columns=list(‘dabc’))
df
image_1cggg67eqe1e1krk1qdp110n14ks13.png-2.6kB
对行索引进行排序
df.sort_index()
image_1cggg6v3apf4tra1bg2sdl1k0i1g.png-2.7kB
6.2 列索引排序(axis=1)
对列索引进行排序
df.sort_index(axis=1)
image_1cggg7jii7pj1aq62onf81vrq1t.png-2.7kB
6.3 列索引降序排序(axis=1 , ascending=Flase)
对列索引进行排序
df.sort_index(axis=1,ascending=False)
image_1cgggibr815ld11efgj6145445s4k.png-2.6kB
7 pandas快速进阶 - 简单的统计
df=DataFrame([[1.4,NA],[7.1,-4.5],[NA,NA],[0.75,-1.3]],
index=list(‘abcd’),columns=[‘one’,‘two’])
df
image_1cggho711fol1rf9hv62i8bln5h.png-3.6kB
7.1 简单求和sum(axis=0/1,skipna=Flase/True)
求和默认省略NaN值,按列方向求和
df.sum()
image_1cgghsem3m931s0k1vsa4e63b26b.png-2.7kB
按行方向求和
df.sum(axis=1)
image_1cgghsv9d1gq01hca6bh2n71o2178.png-3.2kB
7.2 求平均值mean(axis=0/1,skipna=Flase/True)
df.mean(axis=1)
image_1cgghvdhdfuqeuo7mf1pr8bcn82.png-3.4kB
df.mean(axis=1,skipna=False)
image_1cgghueu417r41s0b1681hjogd87l.png-3.2kB
7.3 累积求和
df.cumsum() # 默认会自动跳过NaN值
image_1cggi2ith1vc21v6p11ras8spq98f.png-3.7kB
7.4 数据信息查看
7.4.1 df.describe()
df.describe()
image_1cggiloueak51liamrt1vonhbrbb.png-13kB
7.4.2 df.info()
df.info()
image_1cggimfs5njh1n1didv9l51j9fbo.png-9.9kB
7.4.3 含有字符串类型的数据的describe
series=Series([‘a’,‘a’,‘c’,‘d’]*4)
series.describe()
image_1cggjit1d3m217db1ivmmc1efpep.png-3.1kB
7.5 数据筛选
7.5.1 unique() - 从一组数据中抽取唯一值的方法
series2=Series([‘a’,‘a’,‘c’,‘d’]*4)
series2.unique()
array([‘a’, ‘c’, ‘d’], dtype=object)
7.5.2 value_counts()
series2.value_counts()
image_1cggk1ugn1uuh1hst1u5s1hgv9heg6.png-1.9kB
7.5.3 pd.value_counts()
pd.value_counts(series2.values,sort=True,ascending=True)
image_1cggk34oh1j241ln71vv11uhq1rdugj.png-1.9kB
7.5.4 isin() - 判断数据集中的数据是否为传入该函数中参数的子集
mask = series2.isin([‘c’,‘d’]) # mask索引
series2[mask]
image_1cggke38v19c4oot1cfvk6ls7bhg.png-3.5kB
7.5.5 value_counts与apply结合
data=DataFrame({‘Qu1’:[1,3,4,3,4],‘Qu2’:[2,3,1,2,3],‘Qu3’:[1,5,2,4,4]})
data
image_1cggl5lviavk19sckhv1fp91dlbmt.png-4.1kB
统计每一列数据每个值出现的次数
data.apply(pd.value_counts)
第一列为所有数据的唯一值
第二列表示第一列中值在第二列‘Qu1’中出现的次数
data.apply(pd.value_counts).fillna(0)
1.png-5.9kB
8 NaN值的处理
8.1 isnull()/notnull()
from numpy import nan as NA
string_data=Series([‘上海’,NA,‘南京’,‘北京’,])
string_data
image_1cgglo6po8t7ep11fja91u1eo62j.png-3.5kB
mask=string_data.isnull()
string_data[mask]
1 NaN
dtype: object
string_data[~mask] # 取反
等价于
notnull=string_data.notnull()
string_data[notnull] # 获取非NaN值
image_1cgglq22rp6d14pecvdhijfj130.png-3kB
8.2 dropna()
df=DataFrame([[1,6.5,3.],[1,NA,NA],[NA,NA,NA],[NA,6.5,30]])
df
image_1cggn22g0rh66441fo51fqi1le89.png-4.6kB
8.2.1 dropna()默认参数
clean=df.dropna()
clean
image_1cggn6dcv1bd64j116rj12751ocn1m.png-1.8kB
8.2.3 dropna(how=‘any/all’,axis=0/1)
clean1=df.dropna(how=‘all’,axis=0) # 删除所有列数据都为NA的行
clean1
image_1cggn8ilb1vcs8hg5j6139r7fh2j.png-4kB
8.3 fillna()
8.3.1 直接替换所有NaN值
df=DataFrame([[1,2,NA],[1,3,5],[NA,2,4],[1,2,NA],[2,4,5],[0,NA,3]])
df
image_1cggo5khffqe1h3m1kcjhk6kj30.png-6.6kB
df.fillna(0)
image_1cggo6kucbukh4qifnka1fno3d.png-5.5kB
8.3.2 通过字典替换对制定列替换为指定值
df.fillna({0:123,1:888,3:-1}) # 不存在的列不做处理
image_1cggo8kuu1h6o45v18hq15c6ll33q.png-6.6kB
8.3.3 fillna(inplace=False/True) - 是否修改原数据
9 python字符串操作技巧
str = “a,b, guido”
9.1 str.split()
#将字符串分割成数组
result = str.split(",")
result
[‘a’, ‘b’, ’ guido’]
9.2 ‘#’.join(list) - 将列表中每个字符串之间以’#‘连接
str2=’#’.join(result)
str2
‘a#b# guido’
9.3 str.replace(‘old’,‘new’)
str2.replace(’#’,’ ‘) # 将’#’ 全部替换成空格
[‘a’, ‘b’, ’ guido’]
9.4 str.strip()
#去除字符串前后的空格,包含回车换行
newresult = [x.strip() for x in result]
newresult
[‘a’, ‘b’, ‘guido’]
9.5 in
str = “a,b, guido”
“a” in str >> True
“c” in str >> False
9.6 str.find()
#用find方法检测字符串,如果查找不到,返回-1;如果查找到,返回字符串索引
val.find(“c”)
val.find(“b”) #逗号也算一个字符
-1
2
9.7 str.count()
#统计某个字符出现的次数
val.count(“a”)
val.count(" ") #统计空格出现的个数1
2
9.8 利用正则进行匹配分割(不可用于替换)
text = “foo bar\t baz \tqux”
strList = re.split(’\s+’,text) #以空格分割
strList[‘foo’, ‘bar’, ‘baz’, ‘qux’]
Pandas_part02
1 pandas快速进阶 - 时间序列
1.1 获取时间
from pandas import Series,DataFrame
import pandas as pd
import numpy as np
from datetime import datetime
now =datetime.now()
nowdatetime.datetime(2018, 6, 22, 9, 13, 12, 46341)
now.year,now.month,now.day(2018, 6, 22)
1.2 日期类的加减运算
1.2.1 日期类型加减
delta=datetime(2011,1,7) - datetime(2008,5,12,8,15)
delta,delta.days,delta.seconds(datetime.timedelta(969, 56700), 969, 56700)
1.2.2 timedelta模块
from datetime import timedelta
start=datetime.now()
future = start + timedelta(365)
futuredatetime.datetime(2019, 6, 22, 9, 27, 51, 221740)
1.3 日期类型与字符串转换 - datetime.datetime模块
1.3.1 str()
stamp=datetime.now()
stamp
str(stamp) # 强制转为为字符串datetime.datetime(2018, 6, 22, 9, 31, 12, 779236)
‘2018-06-22 09:31:12.779236’
1.3.2 strftime() - datetime --> str
stamp.strftime(’%Y-%d-%m’)
stamp.strftime(’%d/%m/%Y’)
value=stamp.strftime(’%Y-%m-%d’)
value‘2018-22-06’
‘22/06/2018’
‘2018-06-22’
1.3.3 strptime() - str --> datetime
datetime.strptime(value,’%Y-%m-%d’)datetime.datetime(2018, 6, 22, 0, 0)
datestrs=[‘24/4/2018’,‘22/6/2018’]
[datetime.strptime(x,’%d/%m/%Y’) for x in datestrs] # 列表推导式[datetime.datetime(2018, 4, 24, 0, 0), datetime.datetime(2018, 6, 22, 0, 0)]
1.4 日期类型与字符串转换 - dateutil.parser.parse模块
from dateutil.parser import parse
parse(‘2018-06-22’)datetime.datetime(2018, 6, 22, 0, 0)
parse(‘Jan 31,1997 10:45 PM’)datetime.datetime(2018, 1, 31, 22, 45)
parse(‘6/12/2011’,dayfirst=True)datetime.datetime(2011, 12, 6, 0, 0)
2 pandas中日期时间处理
2.1 to_datetime(datestrs) - str --> datetime
datestrs=[‘24/4/2018’,‘22/6/2018’]
pd.to_datetime(datestrs)DatetimeIndex([‘2018-04-24’, ‘2018-06-22’], dtype=‘datetime64[ns]’, freq=None)
2.2 pandas中日期时间缺失值处理与切片
idx=pd.to_datetime(datestrs+[None])
idxDatetimeIndex([‘2018-04-24’, ‘2018-06-22’, ‘NaT’], dtype=‘datetime64[ns]’, freq=None)
'NaT’pandas中的时间格式的NaN值,not a time
idx[1]
Timestamp(‘2018-06-22 00:00:00’)
idx.isnull()
pd.isnull(idx)array([False, False, True])
2.3 datetime格式定义
image_1cgik6kq51fsm15spbjj148u1ogo9.png-256.8kB
2.4 创建以时间为索引的Series数据
from pandas import Series,DataFrame
import pandas as pd
import numpy as np
from datetime import datetime
dates=[datetime(2011,1,2),datetime(2011,1,5),datetime(2011,1,7),
datetime(2011,2,8),datetime(2011,1,10),datetime(2011,2,12)]
ts=Series(np.random.randn(6),index=dates)
ts
image_1cgilcgdn1qs41b1o146qjrr1s5jm.png-6.5kB
2.4.1 时间格式索引切片
ts[‘2011-01-02’]
ts[‘01/02/2011’]
ts[‘20110102’]
2011-01-02 0.157058
dtype: float64
按月份获取数据
ts[‘2011-2’] # 获取一月份的数据
image_1cgilnm7m1smr1btg9mt15tq64t13.png-3.4kB
2.5 通过pd.date_range()方法船舰一组时间日期序列
2.5.1 pd.date_range(starttime,periods=))
long_str=Series(np.random.rand(1000),
index=pd.date_range(‘1/1/2000’,periods=1000))
long_str.head(2)
image_1cgilqs8c1vdtq8ecc8npb6j70.png-3.9kB
只获取2001年的数据
long_str[‘2001’].head() # 只获取2001年的数据,显示前五条
image_1cgilst411jm31bt818ohbgf4af8d.png-6.4kB
2.5.2 pd.date_range(starttime,endtime))
index=pd.date_range(‘1/4/2012’,‘6/1/2012’)
index
image_1cgim2nic16sc8671aich0q13g5bq.png-16.7kB
2.5.3 pd.date_range(start/end=,periods=))
pd.date_range(end=datetime.now(),periods=6) # 从当前时间往前推6天
image_1cgim6h1lb8pt0h14dm101210lic7.png-11.6kB
3 pandas数据规整pd.merge()
3.1 创建数据集
from pandas import Series,DataFrame
import pandas as pd
import numpy as np
df1=DataFrame({‘key’:[‘b’,‘b’,‘a’,‘c’,‘a’,‘a’,‘b’],‘data1’:range(7)})
df2=DataFrame({‘key’:[‘a’,‘b’,‘d’],‘data2’:range(3)})
image_1cginomrv1kc0ojb1hcs1sk81opqck.png-4.8kB
image_1cginpkrtnol1nf01tml1k7t118cdh.png-2.6kB
3.2 pd.merge(df1,df2) # 必须有相同的列名
pd.merge(df1,df2) # 寻找相同的列名,取交集
pd.merge(df1,df2,on=‘key’) # 按照指定的列取交集
image_1cginrq5vmgf2oe1b6a1h23761eb.png-5.5kB
3.2 pd.merge(df3,df4,left_on/right_on) - 无相同的列名
df3=DataFrame({‘lkey’:[‘b’,‘b’,‘a’,‘c’,‘a’,‘a’,‘b’],‘data1’:range(7)})
df4=DataFrame({‘rkey’:[‘a’,‘b’,‘d’],‘data2’:range(3)})
pd.merge(df3,df4,left_on=‘lkey’,right_on=‘rkey’)
image_1cgio9v9l6k9lri1hi8gbc1mnkeo.png-5.9kB
3.3 pd.merge(df1,df2,how=‘outer/left/right’) # 需有相同的列名称
取并集
pd.merge(df1,df2,on=‘key’,how=‘outer’)
image_1cgiomlmg13cttg13mniqe79u9.png-8.4kB
左连接,取满第一个df中的所有数据,第二个df在对应位置填充对应值,无内容则填充NaN值
pd.merge(df1,df2,how=‘left’)
image_1cgiooq2seou1cc81jp1do5ep1m.png-7.1kB
右连接,取满第二个df中的所有数据,第一个df在对应位置填充对应值,无内容则填充NaN值
pd.merge(df1,df2,how=‘right’)
image_1cgiopj56goqogs1oju1o913t13.png-6.9kB
3.4 多个列连接
left = DataFrame({‘key1’:[‘foo’,‘foo’,‘bar’],‘key2’:[‘one’,‘two’,‘one’],‘lval’:[1,2,3]})
right = DataFrame({‘key1’:[‘foo’,‘foo’,‘bar’,‘bar’],‘key2’:[‘one’,‘one’,‘two’,‘one’],‘rval’:[4,5,6,7]})
pd.merge(left,right,on=[‘key1’,‘key2’],how=‘outer’)
image_1cgipbr2211apbi317f8ljai7t20.png-7.8kB
4 pandas - 合并Series数据集 - pd.concat()
s1=Series([‘a’,‘b’])
s2=Series([‘c’,‘d’,‘e’])
s3=Series([‘f’,‘g’])
4.1 pd.concat() - 默认axis=0 合并后仍为Series数据
pd.concat([s1,s2,s3]) # 此时还是Series数据
image_1cgits78m1pq9poq1rpq2dnu3j9.png-3.4kB
4.2 pd.concat(df1,df2,axis=1) 合并数据为DataFrame数据
pd.concat([s1,s2,s3],axis=1) # 此时还是Series数据
image_1cgituahh12q9a0c18rp19bf1ooom.png-7.4kB
4.3 pd.concat(df1,df2,axis=1,join=) 合并数据为DataFrame数据
s4=pd.concat([s1*5,s3])
s4
image_1cgiu71evgjf52r1cr017q62ur13.png-2.5kB
pd.concat([s1,s4],axis=1,join=‘inner’) # join = ‘inner’
image_1cgiub16j1kmmr2linlk8kopn1g.png-1.6kB
4.4 pd.concat([df1,df2,…],keys=[key1,key2,…])生成层次化索引Series数据结构
pd.concat([s1,s2,s3],keys=[‘one’,‘two’,‘three’])
image_1cgiugv411o0k71gui51dek10981t.png-4.2kB
result[‘one’]
image_1cgiulpcg1vgr5ss4nh40du6b2q.png-1.8kB
result[‘one’][‘a’]
1
4.5 含有重复索引的Series数据打补丁 - combine_first()
from numpy import nan as NA
a = Series([NA,2.5,NA,3.5,4.5,NA],index=list(“fedcba”))
b = Series(np.arange(len(a)),dtype=np.float64,index=list(“fedcba”))
pd.concat([a,b])
image_1cgivd45u1oos160rgk3141214ql41.png-4.4kB
image_1cgive2ofdu6icvatakqd1p8o4e.png-4.2kB
image_1cgivgbop5hs7ek1jpl1lb7mth58.png-8.1kB
c = a[2:]
result=c.combine_first(b[:-2])
#重复索引的情况下,用后一个Series中的数据为前一个Series数据打补丁,仅填补NaN值
result
image_1cgivbmhr1u9fkig1iar1h1c1k5q3k.png-3.7kB
4.5 DataFrame数据打补丁 - combine_first()
用df2的数据为df1打补丁
df1=DataFrame({‘a’:[1.,NA,5.,NA], ‘b’:[NA,2.,NA,6.], ‘c’:range(2,18,4)})
df2=DataFrame({‘a’:[5.,4.,NA,3.,7.], ‘b’:[NA,3.,4.,6.,8.]})
df1.combine_first(df2)
image_1cgj0depq1do31u991fj41cfh1lis5l.png-5.7kB
image_1cgj0e5o61o6v1oka15sn1apke3q62.png-4.9kB
image_1cgj0ev2ochv1v9e1cg31mqurea6f.png-8.1kB
5 数据的重塑与旋转
data = Series(np.random.randn(10),index= [list(“aaabbbccdd”),[1,2,3,1,2,3,1,2,2, 3]])
image_1cgj0parqo2p1g351aik18rj8lj6s.png-9.3kB
5.1 Series.unstack()/stack() - 行索引与列索引相互转换
result = data.unstack()
image_1cgj12e1g17mk1dkotrf92r1q347m.png-10.3kB
result.stack() # 默认是忽略NaN值的,所以stack()与unstack()是可逆的操作
image_1cgj14im11jv5ankpg9180s1lk783.png-9.9kB
result.stack(dropna=False) # 默认是忽略NaN值的,所以stack()与unstack()是可逆的操作
image_1cgj25apl1a0pn8i5vr2bl56v90.png-13.7kB
AttributeError: ‘Series’ object has no attribute ‘stack’
5.2 DataFrame.unstack()/stack() - df转换后均为Series数据
data = DataFrame(np.arange(6).reshape(2,3),index=pd.Index([“Ohio”,“Colorado”],
name=“state”),columns=pd.Index([“one”,“two”,“three”],name=“numbers”))
5.2.1 不指定层级转换行和列
result=data.stack()
result
result.unstack()
image_1cgj2esm39ef1sst1r291mhl6g9d.png-5.4kB
image_1cgj2ko18tb01mvi55kmeq10uba7.png-14.7kB
result2 = data.unstack()
result2
unstack默认转换的是最内层的索引
result2.unstack()
image_1cgj2njpt14a111kl3ajki1ta6ak.png-16.5kB
5.2.2 指定层级转换行和列(0为最外层,层级索引外内依次加1)
image_1cgj31fehdn1ar31hd312fp15asb1.png-14.2kB
在对DataFrame进行unstack操作时,作为旋转轴的级别将会成为结果中的最低级别
data = DataFrame(np.arange(6).reshape(2,3),index=pd.Index([“Ohio”,“Colorado”],
name=“state”),columns=pd.Index([“one”,“two”,“three”],name=“numbers”))
image_1cgj3vk2ismb36p1umiv1ijjtbe.png-5.4kB
image_1cgj42s9jjo43ubo7ne3q1eoobr.png-8.3kB
df=DataFrame({‘left’:result,‘right’:result+5},
columns=pd.Index([‘left’,‘right’],name=‘side’))
image_1cgj46jjr10gf8kp1ls6i8ocsrc8.png-19.7kB
image_1cgj4r5671jn95lm1cf10thh03cl.png-26.3kB
6 pandas 数据过滤、清理及转换
data=DataFrame({‘k1’:[‘one’]*3 + [‘two’] * 4,‘k2’:[1,1,2,3,3,4,4]})
image_1cgj5e3l0suk1g2o1ldckq01028d2.png-5.6kB
6.1 重复值检查及删除
6.1.1 df.duplicated() - 重复值查询
默认对所有列进行重复值检查
data.duplicated()
传入列名,对指定列进行重复值检查
data.duplicated(‘k1’)
image_1cgj5tcarces1eb7a371ea3fildf.png-26.2kB
6.1.2 df.drop_duplicates() - 重复值删除
默认对所有列进行重复值查询,并且保留第一行出现的值
data.drop_duplicates()
传入列名,对指定列进行重复值检查,设置keep关键字参数,keep=‘first’/‘last’
data.drop_duplicates(‘k1’,keep=‘last’)
image_1cgj63do4mt51j5a1j5five1r4jds.png-18.1kB
6.2 pandas 利用函数和映射进行转换
data=DataFrame({‘food’:[‘bacon’,‘pulled pork’,‘bacon’,‘Pastrami’,‘corned beef’,
‘Bacon’,‘pastrami’,‘honey ham’,‘nova lox’],
‘ounces’:[4,3,12,6,7.5,8,3,5,6]})
image_1cgj9oefen239o01mr16mmi2fe9.png-16.1kB
meat_to_animal={‘bacon’:‘pig’,‘pulled pork’:‘pig’,‘pastrami’:‘cow’,‘honey ham’:‘pig’,‘nova lox’:‘salmon’,‘corned beef’:‘cow’
}
data[‘animal’]=data[‘food’].map(str.lower).map(meat_to_animal)
等价于
data[‘animal’]=data[‘food’].map(lambda x:meat_to_animal[x.lower()])
image_1cgjaeopc1r611kao12r0n6o6p8gg.png-16.1kB
6.3 数据替换 Series.replace()
6.3.1 Series.replace()- 单值或多值(列表)替换为一个值
data=Series([1.,-999,2.,-999,-1000,3.])
image_1cgj9rsdg80ci2v6t211fj204em.png-27.3kB
6.3.2 Series.replace() - 不同的值做不同的替换
data.replace({-999:NA,-1000:0}) # 替换多个值
data.replace([-999,-1000],[NA,0]) # 替换多个值
image_1cgja4ja4tph1ffm13u15j61irtg3.png-21.6kB
6.4 数据分组 pd.cut(Series,bins)
6.4.1 数据分组
age=[20,22,25,27,21,23,37,31,61,45,41,32]
bins=[18,25,35,60,100]
cats = pd.cut(age,bins)
image_1cgjasfk5jheh411inf1pfn1m34mn.png-25.1kB
6.4.2 为分组数据加上标签
group=[‘Youth’,‘YouthAdult’,‘MinddleAged’,‘Senior’]
pd.cut(age,bins,labels=group)
image_1cgjbcn74vkafsu1b5kvmn1g2ink.png-28.9kB
Pandas_part3
from pandas import Series,DataFrame
import pandas as pd
import numpy as np
from numpy import nan as NA
1 pandas高级 - 数据拆分
1.1 pd.cut(data,n)
data = np.random.rand(20)
result = pd.cut(data,4) # cut将data数据按值区间分为4组
result.value_counts()
image_1cgq8nkc61nlemg9qabfqa1r9.png-4.4kB
result1 = pd.cut(data,4,precision = 2) # cut将data数据按值区间分为4组,保留两位有效数字
result1.value_counts()
image_1cgq8oda519v83o7139j1q3ppq4m.png-4.2kB
1.2 pd.qcut(data,n)
data_n = np.random.randn(1000)
result2 = pd.qcut(data_n,4) # cut将data数据按个数均分成四组
result2.value_counts() # 统计落在每个区间的元素
image_1cgq8porg1rjp1rbl13ifa61lpq13.png-4.9kB
2 pandas数据过滤与检测
np.random.seed(number) # number是生成随机数的种子,可以通过种子来控制产生随机数
np.random.randn() # 默认生成随机数的种子数是当前时间的时间戳
定义一个种子数,种子数默认只能运行一次
np.random.seed(34567)
np.random.rand()
同一个种子生成的随机数一样
0.542289024619481
np.random.seed(12345)
data = DataFrame(np.random.randn(1000,4))
data.head()
image_1cgqclj1k6481nob9f71c4uq5v9.png-14kB
data.describe()
image_1cgqcm9vj16t05hehkl610c9bm.png-20.6kB
col = data[3]
筛选出第四列中绝对值大于3的数
col[np.abs(col>3)]
image_1cgqcnvja1ojrmjh6t1pen1kob1j.png-2.8kB
筛选出任意行出现一列绝对值大于3的数据
data[(np.abs(data>3)).any(1)]
image_1cgqcoos1t4s1lfo1o5316aknii20.png-15kB
将所有绝对值大于3的整数设置为3,绝对值大于3的负数,设置为-3
data[np.abs(data)>3] = np.sign(data)*3 # 直接修改原数据
3 pandas 读取文件数据
3.1 pd.read_csv()
语法:pd.read_csv(path,sep=’’,header=None,names=[],index_col=‘col_name’/col_list)
常用参数设置:
sep=’,’ : 指定分隔符
header=None :不读入表头
names=[]:传入列名列表,指定列名
index_col=’’:将指定列设置为行索引
index_col=[]:传入列名列表,构成多层索引数据
skiprows=[]:传入行索引列表,防止有部分数据存在注释的现象
na_values=[]:传入值列表或者字典,将指定数据替换为NaN值
image_1cgqivvltqi2bas29i1avns59m.png-42kB
image_1cgqj1063d529scl521unaai113.png-39.3kB
image_1cgqj4rnd3vn10br13tc1ps613c71g.png-37.7kB
image_1cgqj6brcomh1j7u1qm01nai31u1t.png-44.1kB
3.2 pd.read_table() - 阅读.txt/.json格式文件
语法:pd.read_table(path,sep=’’)
默认读入的数据为1列
sep=’,’ : 指定分隔符,可以使用简单的正则表达式,如:’\s+'匹配1个或多个空格
image_1cgqisiu3laie6uemt1i4q196b9.png-55.6kB
4 pandas写入文件
4.1 pandas直接写入文件
语法:df.to_csv(path/sys.stdout,index=False/True,header=False/True,sep=’’,columns=[],na_rep=[‘NULL’])
index=False/True:是否写入行索引
header=False/True:是否写入列索引
sep=’’:指定存入数据的分隔符
columns=[]:传入需要输出的列数据,保存指定数据内容
na_rep=[‘NULL’]:将所有形式的NaN值统一替换为’NULL’,可以设为其他值
sys.stdout:在控制台预先输出存入数据的格式
image_1cgqjphk519p71k9t2l012ih15tp2a.png-46.4kB
4 pandas高级篇 - 数据聚合与分组计算
data = DataFrame({‘key1’:[‘a’,‘a’,‘b’,‘b’,‘a’],‘key2’:[‘one’,‘two’,‘one’,‘two’,‘one’],
‘data1’:np.random.randn(5),‘data2’:np.random.randn(5)})
image_1cgqnt7eo6b61tv5rugbsj1gfd9.png-12.8kB
4.1 取某列数据进行分组
选取data1中的数据,按照key1列数据进行分组,
grouped = data[‘data1’].groupby(data[‘key1’])
image_1cgqo1og612kh1c391a9s15lt1q1im.png-6kB
选取data1列数据然后根据key1和key2进行分组
grouped2 = data[‘data1’].groupby([data[‘key1’],data[‘key2’]])
image_1cgqo2r6m18dc13fms1d1rmha8o33.png-8.7kB
4.2 .size()/.count()
获取分组后每一组中相应元素出现的次数
data.groupby([‘key1’,‘key2’]).size()
data.groupby([data[‘key1’],data[‘key2’]]).count()
image_1cgqo6rma1hfr8mevnr10er1k883g.png-24.4kB
4.3 遍历分组结果 & 将分组结果存为字典
for name ,group in data.groupby(‘key1’):
print(name)
print(group)
image_1cgqodorknv3kae192ip08m554t.png-10.6kB
image_1cgqoie771ndmjud1ms2ehtdo85a.png-17.4kB
4.4 按数据类型分组
grouped3=data.groupby(data.dtypes,axis=1)
dict(list(grouped3))
image_1cgqol8nh1evk1jek1opq1vfp1eve5n.png-5.1kB
image_1cgqolkk42l11bov1f1t1mhhso64.png-15.2kB
4.5 选择分类结果中的一个或一组进行进行聚合计算
4.5.1 通过[]操作符操作,返回一个Series
data[‘data2’].groupby([data[‘key1’],data[‘key2’]]).mean()
data.groupby([‘key1’,‘key2’])[‘data2’].mean()
image_1cgqp43031f1s16481rho73kcr271.png-6.9kB
4.5.2 通过[[]]操作符操作,返回一个DataFrame
data.groupby([‘key1’,‘key2’])[[‘data2’]].mean()
image_1cgqp502tv2q1317ir6s33sa87e.png-7.1kB
4.5.3 根据字典映射进行分组聚合
df = DataFrame(np.random.randn(5,5),columns=list(‘abcde’),index=[‘x’,‘y’,‘z’,‘w’,‘r’])
mapping={‘a’:‘red’,‘b’:‘red’,‘c’:‘blue’,‘d’:‘blue’,‘e’:‘red’,‘f’:‘orange’}
by_columns = df.groupby(mapping,axis=1)
by_columns.sum()
image_1cgqskvpb9j01lqfrne1ubvks487.png-17.4kB
image_1cgqsleq4e6h1j0o162v1anos3q8k.png-11.2kB
seriesMap=Series(mapping)
df.groupby(seriesMap,axis=1).count()
image_1cgqso85i1bgk1c6kqb9u1hrjs9h.png-14.4kB
4.6 常用的聚合函数
QQ截图20180625145421.png-64.9kB
4.7 agg()函数传入自定义聚合函数
4.7.1 使用.agg()函数传入自定义函数对分组数据进行聚合运算
dict_obj = {‘key1’ : [‘a’, ‘b’, ‘a’, ‘b’, ‘a’, ‘b’, ‘a’, ‘a’],
‘key2’ : [‘one’, ‘one’, ‘two’, ‘three’, ‘two’, ‘two’, ‘one’, ‘three’],
‘data1’: np.random.randint(1,10, 8), ‘data2’: np.random.randint(1,10, 8)}
df=DataFrame(dict_obj)
df
image_1cgqsrems1kdd1r961ijg8ucoaq9u.png-10.8kB
image_1cgqstblt15c2k95988bu31ofpab.png-34.1kB
4.7.2 使用.agg()函数传入多个函数对分组数据进行聚合运算
df.groupby(‘key1’).agg([‘mean’,‘std’,‘count’,peak_range]) #系统内置函数需要引号
image_1cgqt7lgogd31uifeg0c6tv7bao.png-15.1kB
df.groupby(‘key1’).agg([‘mean’,‘std’,‘count’,(‘ptp’,peak_range)]) #为自定义函数起别名
image_1cgqtc1t8rep15je6va8vf1kivb5.png-14.5kB
4.7.3 使用字典实现不同列不同的聚合函数
dict_mapping = {‘data1’:[‘mean’,‘max’],‘data2’:[‘sum’]}
df.groupby(‘key1’).agg(dict_mapping)
image_1cgqtornoabhvvv7o1igmgi3ci.png-9.1kB
4.7.4 as_index = True / False
df = pd.DataFrame(data={‘books’:[‘bk1’,‘bk1’,‘bk1’,‘bk2’,‘bk2’,‘bk3’], ‘price’: [12,12,12,15,15,17]})
image_1cgqu2vrj1i011674g7u12pj6hpdf.png-6.7kB
将分组的列作为索引
df.groupby(‘books’, as_index=True).sum()
image_1cgqu6a4q2lv1q4jqkck13p68ds.png-8.6kB
不将分组的列作为索引
df.groupby(‘books’, as_index=False).sum()
image_1cgqu6nvr1omm1018fsn1ki1k1qe9.png-8.5kB
4.8 apply() - 最通用的GroupBy方法
tips = pd.read_csv(‘data/tips.csv’)
为tips数据集田间新的一列,作为客户给的消费占消费总额的百分比
tips[‘tip_pct’]=tips[‘tip’]/tips[‘total_bill’]
image_1cgqv7ta4m7u1kkn9eb1u9915jgem.png-18kB
定义函数,筛选出小费占比最大的前五条数据
def top(df,n=5,columns=‘tip_pct’):
return df.sort_values(by=columns)[-n:] # 升序排序,取后n条
image_1cgqv8v53c8115rr1hik181i1e0cf3.png-21.6kB
4.8.1 对数据集按照是否抽样进行分组,并通过apply()函数调用top函数
tips.groupby(‘smoker’).apply(top)
image_1cgqvadgn1ed2bd7umj1it6jccg0.png-36.5kB
4.8.2 在apply()函数中调用top函数并传入参数
tips.groupby(‘smoker’).apply(top,n=2,columns=‘total_bill’)
image_1cgqvgubp117015hkbak16ra5jigd.png-20.9kB
image_1cgqvqh42ilc15qi1j1kpj7ojfha.png-58.7kB
4.8.3 apply()函数结合pd.cut()
df = pd.DataFrame({‘data1’: np.random.randn(1000),‘data2’: np.random.randn(1000)})
image_1cgr16mu611351tr43uiv2bd82i7.png-10.7kB
result = pd.cut(df.data1,4)
def get_stats(group):
return { ‘min’: group.min(), ‘max’: group.max(),‘count’:group.count(), ‘mean’: group.mean() }
grouped = df.data2.groupby(result)
grouped.apply(get_stats).unstack()
image_1cgr18q0s70uieb11b41fa4linik.png-19.1kB
参考资料:
用pandas中的DataFrame时选取行或列