《利用Python进行数据分析》学习笔记之Pandas基础

1. Series

类似于一维数组的对象: 由一组数据(各种numpy对象)和一组与之相关的索引组成。分别有两个属性,.values 和 .index

(1)创建Series
  • 直接定义,包括定义index
  • 输入一个dict,转成Series
import pandas as pd
from pandas import DataFrame,Series
import numpy as np
from numpy import random
#直接定义Series
obj=Series([-4,7,8,9],index=['a','b','c','d'])
#用字典创建Series
dict={'a':-4,'b':7,'c':8,'d':9}
obj1=Series(dict)
(2)利用索引查找数据
obj['a']
obj[['a','b']]
a   -4
b    7
dtype: int64
(3)利用布尔型索引过滤数据
obj[obj>0]
b    7
c    8
d    9
dtype: int64
(4)Series自动对齐不同索引数据
  • 重传index到已有index的Series,或者dict中,则values会自动与index对齐。(找不到values的index,会填充NAN)
#在有index的Series传入index
obj1=Series(obj,index=['c','d','e','f'])   
#在有index的dict传入index
obj2=Series(dict,index=['c','d','e','f']) 

2. DataFrame

是表格型数据结构,含有一组有序的列,每列可以是不同的值类型。
可看作是由一组Series组成(共用同一个索引)

(1)创建DataFrame
  • 直接定义,,包括index,columns
  • 输入一个有列表或者numpy数组的dict,转成DataFrame
#直接定义
data = [[1,2,3],[4,5,6]]
index = [0,1]
columns=['a','b','c']
df = pd.DataFrame(data=data, index=index, columns=columns)
#利用dict转成DataFrame
dict={'a':[1,2,3],'b':[4,5,6],'c':[7,8,9]}
df1=DataFrame(dict,index=['one','two','three'])
(2)利用列名取数据
  • 通过列名或者属性的方式可以从DataFrame获取一组Series
df1['a']
df1.a
one      1
two      2
three    3
Name: a, dtype: int64
(3)赋值、创建新列
df1['a']=1
df1['d']=4
(4)删除列
del df1['d']

3.Series和DataFrame基本功能

(1)重新索引


.reindex()

  • 可以重新索引行和列,对数据重新排列。
  • 若索引无对应数据,可以填充插值,插值默认为空.参数method、fill_value分别用于 插值方式和 设置缺失值的替代值
df2=df1.reindex(index=['two','one','four','three'],columns=['b','c','a','e'],fill_value=22)
print (df2)
        b   c   a   e
two     5   8   1  22
one     4   7   1  22
four   22  22  22  22
three   6   9   1  22
(2)删除某一行或某一列

  • 删除行可以直接写入 index的名字
  • 删除列除了写入columns名,还需要指定axis
df3=df2.drop('four')
df3=df2.drop('e',axis=1)
(3) 索引

  • Series的索引,可用Index ,也可用数字下标
s1=df3['b']
s1['two']
s1[['two','one']] # 用数组列出,要用[ ]括起来
s1['two':'four']  # 标签切片的右区间是闭合的
s1[1:3]           # 标号切片的右区间是开放的
one      4
four    22
Name: b, dtype: int64
  • DataFrame的索引

1. 列索引:直接用列的字段名索引 (注意:行索引不能直接用字段名)

df3['b']
df3[['b','c']]
bc
two58
one47
four2222
three69

2. .loc 通过标签索引数据

  • 先写行标签,后写列标签
  • 列举多个列,要用数组,用[ ]括起来
  • 列举切片,则无需用[ ]括起来。注意标签切片的右括号是闭合的
df3.loc[['two','one']]   #索引多行,行名用数组
df3.loc['two':'three']   #索引多行,行名用切片
df3.loc['two',['b','a']] #索引某行多列,列名用数组
df3.loc['two','b':'a']   #索引某行多列,列名用切片
df3.loc[:,['b','a']]     #索引某列
ba
two51
one41
four2222
three61

3..iloc 通过标号获取数据

  • 先写行号,再写列号
  • 可用单值,也可用切片,注意:标号切片的右括号是开区间的
df3.iloc[1:3,1:3]
ca
one71
four2222

.ix 结合前两者的混合索引,可同时使用标签和行号,注意:目前.ix已弃用

(4)过滤

  • 使用布尔数组来过滤数据
df3[df3['a']<2]  #先用某一列过滤,返回一个布尔数组,然后通过布尔数组再过滤行
bca
two581
one471
three691
df3[df3<2]=0 #选取特定的值重新赋值
(5)计算方法

  • Series和DataFrame 可以根据 行列索引 自动对齐, 未对齐的默认填充NAN,也可以用fill_value属性,指定填充值
  • .add()
  • .sub()
  • .div()
  • .mul()
(6)DataFrame 和Series 之间的运算

  • 广播
  • 默认 Series的索引,匹配DataFrame的列标签。按行广播
  • 若要 Series的索引,匹配DataFrame的行标签的话,要用axis指定
s1 = df3.loc['two']
s2 = df3['b']
# df4=df3+s1
df4=df3.add(s1)
print (df3)
print (s1)
print (df4)
        b   c   a
two     5   8   0
one     4   7   0
four   22  22  22
three   6   9   0
b    5
c    8
a    0
Name: two, dtype: int64
        b   c   a
two    10  16   0
one     9  15   0
four   27  30  22
three  11  17   0
df5=df3.add(s2,axis=0) #指定s2的索引是匹配行标签,则是按列广播
print (df3)
print (s2)
print (df5)
        b   c   a
two     5   8   0
one     4   7   0
four   22  22  22
three   6   9   0
two       5
one       4
four     22
three     6
Name: b, dtype: int64
        b   c   a
two    10  13   5
one     8  11   4
four   44  44  44
three  12  15   6
(7)排序和排名

1.根据任意轴索引排序

  • 默认为按行标签排序,用axis属性可设置需要排序的轴
  • 默认为升序排序,用 ascending 属性可设置升降序
df3.sort_index()  #默认axis=0,按行标签排序
df3.sort_index(axis=1,ascending=False)  #按列标签排序
cba
two850
one740
four222222
three960

2.根据某个列值排序

df3.sort_values(by='b')
bca
one470
two580
three690
four222222

3.排名

  • 与排序的区别在于,会增设一个排名值(从1开始),同时会根据某种规则破坏平级关系
  • 可以用method设置不同的排名方式
df3.rank(axis=0,method='first') # axis=0 为按列排名, axis=1 为按行排名
bca
two2.02.01.0
one1.01.02.0
four4.04.04.0
three3.03.03.0
(8)汇总和计算描述统计 p155

  • NA值会自动排除,skipna可以设置
  • axis=0 按列计算,axis=1 按行计算
(9)唯一值、值计数、成员资格

Series中的方法

1.唯一值

obj=Series(['a','a','c','d','e','a','b'])
obj.unique()  # 返回的是一个nparray
array(['a', 'c', 'd', 'e', 'b'], dtype=object)

2.值计数

obj1=obj.value_counts()  #常用于统计某个离散值各个类别的频率
print(obj1)
a    3
d    1
c    1
b    1
e    1
dtype: int64

3.成员资格

obj2=obj.isin(['b','c'])
print(obj2)
0    False
1    False
2     True
3    False
4    False
5    False
6     True
dtype: bool
(10)处理缺失数据

1.滤除缺失数据

Series的方法

import numpy as np
from numpy import nan as NA
data=Series([1,NA,3.5,NA,10])
data.dropna()         #用.dropna()的方法
data[data.notnull()]   #通过布尔索引来过滤
0     1.0
2     3.5
4    10.0
dtype: float64

DataFrame的方法

  • 丢弃任何含NA的行
  • 只丢弃全为NA的行
  • 过滤部分,用thresh参数
df3['d']=NA
df4=df3.dropna(axis=1)   #axis=0 为丢掉所有含NAN的行,axis=1 为丢掉所有含NAN的列
df4=df3.dropna(how='all')  # how='all'
df4=df3.dropna(thresh=2)  

2.填充缺失数据

  • .fillna方法
    • 可对所有缺失值赋值
    • 可用词典对不同的列填充不同的值
    • 默认是返回新对象,可用inplace属性 设置对象就地修改
    • 可用method 属性设置不同的插值方式
df3['d']=[6,7,8,9]
df3.iloc[0:2,2:4]=NA
df3.fillna(1)    #可对所有缺失值赋值
df3.fillna({'a':4,'d':5}) #可用词典对不同的列填充不同的值
bcad
two584.05.0
one474.05.0
four222222.08.0
three690.09.0
(11)层次化索引 P153
1.Series

1.创建层次化索引

data=Series(np.random.randn(6),index=[['a','a','b','b','c','c'],[1,2,1,2,1,2]])
print(data)
a  1   -2.403726
   2    0.534817
b  1    1.007619
   2   -0.555399
c  1   -0.715177
   2   -0.850348
dtype: float64

2.Series层次化索引的切片操作

data['a':'b']
data.loc[['a','c']]
data.loc[:,2]    #类似DataFrame中先选行再选列,在层次化索引中先选外层再选内层
a    0.534817
b   -0.555399
c   -0.850348
dtype: float64

3.层次化索引与DataFrame间的转换

data.unstack()       #从层次化索引转换成DataFrame
data.unstack().stack()  #从DataFrame转换成层次化索引
a  1   -2.403726
   2    0.534817
b  1    1.007619
   2   -0.555399
c  1   -0.715177
   2   -0.850348
dtype: float64
2.DataFrame

1.创建层次化索引

  • 每条轴都可以有分层索引
  • 可以给每个层级的索引命名 .names
frame=DataFrame(np.arange(12).reshape(4,3),index=[['a','a','b','b'],[1,2,1,2]],columns=[['Ohio','Ohio','Colorado'],['Green','Red','Green']])
frame.index.names=['key1','key2']
frame.columns.names=['state','color']
frame
stateOhioColorado
colorGreenRedGreen
key1key2
a1012
2345
b1678
291011

2.重排分级顺序

  • .swaplevel (序号1,序号2) :序号为索引层级,从0开始;也可以直接用标签
  • .sort_index(level=序号) :对索引进行排序
frame.swaplevel('key1','key2')
# frame.swaplevel('key1','key2').sort_index(level='key2')
frame.swaplevel(0,1).sort_index(level=0)
stateOhioColorado
colorGreenRedGreen
key2key1
1a012
b678
2a345
b91011

3.将某列作为索引

frame=DataFrame({'a':range(7),'b':range(7,0,-1),'c':['one','one','one','two','two','two','two'],'d':[0,1,2,0,1,2,3]})
frame.set_index(['c','d'])   #把某列作为行索引,该列从DataFrame中移除
frame.set_index(['c','d'],drop=False)   #把某列作为行索引,该列在DataFrame中保留
frame.reset_index( )     #将层次化索引的级别会转到列里面
indexabcd
0007one0
1116one1
2225one2
3334two0
4443two1
5552two2
6661two3

4.DataFrame层次化索引的切片操作

  • 列索引可直接用列名索引
  • 行索引若一级索引有多个索引,则二级索引不能直接索引,要转化
frame=DataFrame(np.arange(12).reshape(4,3),index=[['a','a','b','b'],[1,2,1,2]],columns=[['Ohio','Ohio','Colorado'],['Green','Red','Green']])
frame.index.names=['key1','key2']
frame.columns.names=['state','color']
frame
stateOhioColorado
colorGreenRedGreen
key1key2
a1012
2345
b1678
291011

(1)列索引可以直接用列名

frame['Ohio']             #取最外层的列标签
frame['Ohio','Green']     #取内层的单个列标签
frame['Ohio'][['Red','Green']]  #取内层的多个列标签,先取外层得出一个DataFrame,再取内层
colorRedGreen
key1key2
a110
243
b176
2109

(2)行索引 要用.loc的方法

  • 注意在对行索引的时候,若一级行索引还有多个,对二级行索引会遇到问题!也就是说,无法直接对二级索引进行索引,必须让二级索引变成一级索引后才能对其进行索引!
frame.loc['a']        #取最外层的行标签
frame.loc['a',1]      #取内层层的单个行标签
frame.ix['a',[1,2]]      #取内层层的单个行标签
E:\WinPython\WPy-3662\python-3.6.6.amd64\lib\site-packages\ipykernel_launcher.py:3: DeprecationWarning: 
.ix is deprecated. Please use
.loc for label based indexing or
.iloc for positional indexing

See the documentation here:
http://pandas.pydata.org/pandas-docs/stable/indexing.html#ix-indexer-is-deprecated
  This is separate from the ipykernel package so we can avoid doing imports until
stateOhioColorado
colorRedGreen
key2
112
245

(3)行列一起索引

frame.loc['a']['Ohio','Green']     #先索引行标签,在基础上取列
key2
1    0
2    3
Name: (Ohio, Green), dtype: int32

4.数据聚合与分组运算

df=DataFrame({'key1':['a','a','b','b','a'],'key2':['one','two','one','two','one'],'data1':np.random.randn(5),'data2':np.random.randn(5)})
df
key1key2data1data2
0aone-0.8475440.003861
1atwo1.5102830.623520
2bone-0.0994010.038992
3btwo0.191581-0.927451
4aone0.586113-0.571834
(1)用groupby方法进行分组

Series
  • Series的分组,groupby需要用分组键的值
  • 实际是Series根据分组键进行分组,产生一个新的Series( 分组键'key1',可以看做是层次化索引的外层 )。然后每个分组分别进行计算。最后把计算结果合并展示
  • Series的分组键可以是任意长度的数组。(使用某列时用列值,不能用列名。 比如:需要用df['key'], 不能用 'key')
df['data1'].groupby(df['key1']).mean()
df['data1'].groupby([df['key1'],df['key2']]).mean()
year=np.array([2005,2005,2006,2005,2006])
df['data1'].groupby(year).mean()
2005    0.284774
2006    0.243356
Name: data1, dtype: float64
DataFrame
  • DataFrame的分组,groupby可以用列名。
  • 一般数值列会被聚合,非数值列(‘麻烦列’)会被排除
df.groupby('key1').mean()   #结果中没有key2,因为key2是非数值列被排除
data1data2
key1
a0.4162840.018515
b0.046090-0.444229

groupby 的.size() 的方法。可以返回一个表示各个分组大小的Series

df.groupby(['key1','key2']).size()
key1  key2
a     one     2
      two     1
b     one     1
      two     1
dtype: int64
(2)用层次化索引方法进行分组

  • 会把该层级的同一索引对应的值进行累加/减 等

对行索引的层级汇总

frame.sum(level='key1')
stateOhioColorado
colorGreenRedGreen
key1
a357
b151719

对列索引的层级汇总,要用axis指定

frame.sum(level='color',axis=1)

(3)对groupby对象进行迭代

  • 返回的值 key1为 分组键 ,group为 分组完后的小组。
df.groupby('key1')   #返回的是一个groupby对象
for key1,group in df.groupby('key1'):
    print (key1)
    print (group)
    
for (key1,key2),group in df.groupby(['key1','key2']):
    print (key1,key2)
    print (group)
a
  key1 key2     data1     data2
0    a  one -0.847544  0.003861
1    a  two  1.510283  0.623520
4    a  one  0.586113 -0.571834
b
  key1 key2     data1     data2
2    b  one -0.099401  0.038992
3    b  two  0.191581 -0.927451
a one
  key1 key2     data1     data2
0    a  one -0.847544  0.003861
4    a  one  0.586113 -0.571834
a two
  key1 key2     data1    data2
1    a  two  1.510283  0.62352
b one
  key1 key2     data1     data2
2    b  one -0.099401  0.038992
b two
  key1 key2     data1     data2
3    b  two  0.191581 -0.927451
(4)选取一组或一列的groupby对象

#以下两种方法是等价的
df['data1'].groupby(df['key1'])
df.groupby('key1')['data1']
<pandas.core.groupby.groupby.SeriesGroupBy object at 0x000001C35A75F358>
(5) groupby对象、字典之间的转化

#groupby转成字典
# dict(list(df.groupby('key1')))
#字典转成groupby
mapping={'data1':'a','data2':'b','key1':'c','key2':'d'}
df.groupby(mapping,axis=1).sum()  #以后面的值为分组键
abcd
0-0.8475440.003861aone
11.5102830.623520atwo
2-0.0994010.038992bone
30.191581-0.927451btwo
40.586113-0.571834aone

转载于:https://www.cnblogs.com/laiyaling/p/10062278.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值