《利用python进行数据分析》学习笔记--pandas(1)

    pandas主要的两个数据结构是:Series 和DataFrame

1、Series

series 类似于一维数组,由 索引+数据组成

若不指定索引,则会自动创建0到N-1的整数型索引,

可以用series的values获取数组值,用index获取索引值。

import pandas as pd
obj = pd.Series ([3,6,9,7],index = ['c','b','d','a'])
obj
返回为
c    3
b    6
d    9
a    7
dtype: int64
此时可以通过索引选取值
obj['d']
返回为
9

Numpy的数组运算(布尔型数组过滤、标量乘、数学函数)不会改变索引和值之间的链接

obj * 3
c     9
b    18
d    27
a    21
dtype: int64

np.exp(obj)
c      20.085537
b     403.428793
d    8103.083928
a    1096.633158
dtype: float64

   如果数据存放在一个Python字典中,可以通过字典来创建Series

data = {'JiangSu':20000,'JiangXi':35000,'FuJian':15000,'GuangDong':40000}
obj = pd.Series(data)
obj
返回为
JiangSu      20000
JiangXi      35000
FuJian       15000
GuangDong    40000
dtype: int64

如果只传如一个字典,则Series的索引就是原字典的键。

states = ['FuJian','JiangSu','ZheJiang']
obj1 = pd.Series(data,index = states)
obj1
返回为
FuJian      15000.0
JiangSu     20000.0
ZheJiang        NaN
dtype: float64

在pandas中一般用isnull、notnull检测缺失值。

series最重要的一个功能是:可以在算数运算中自动对齐不同索引的数据

obj +obj1
返回为
FuJian       30000.0
GuangDong        NaN
JiangSu      40000.0
JiangXi          NaN
ZheJiang         NaN
dtype: float64

Series的对象本身和索引都有一个name属性

obj1.name = 'population'
obj1.index.name = 'state'
obj1
返回为
state
FuJian      15000.0
JiangSu     20000.0
ZheJiang        NaN
Name: population, dtype: float64

series也可以通过赋值的方式就地修改

2、DataFrame

dataframe既有行索引,又有列索引,可以被看作由series组成的字典(共用一个索引)

    传入一个由等长列表或Numpy数组组成的字典,如果传入时不加索引,则dataframe自动加上索引

data = {'state':['JiangSu','JiangXi','ZheJiang','GuangDong'],'year':[2008,2009,2010,2011],'pop':[1.5,1.8,2.5,2.9]}
frame = pd.DataFrame(data)
frame
frame2 = pd.dataframe(data,columns = ['year','state','pop','debt'],index = ['one','two','three','four'])
frame2
返回为
        state      year    pop
0    JiangSu    2008    1.5
1    JiangXi    2009    1.8
2    ZheJiang    2010    2.5
3    GuangDong    2011    2.9

frame2 = pd.DataFrame(data,columns = ['year','state','pop','debt'],index = ['one','two','three','four'])
frame2
返回为
        year     state    pop    debt
one    2008    JiangSu    1.5    NaN
two    2009    JiangXi    1.8    NaN
three  2010    ZheJiang   2.5    NaN
four   2011    GuangDong  2.9    NaN

DataFrame一般用索引字段ix来执行

frame2.ix['four']
返回为
year          2011
state    GuangDong
pop            2.9
debt           NaN
Name: four, dtype: object
也可以通过赋值进行修改
frame2['debt'] = 15
frame2
返回为
yearstatepopdebt
one 2008 JiangSu 1.5 15
two 2009 JiangXi 1.8 15
three 2010 ZheJiang 2.5 15
four 2011 GuangDong 2.9 15

 

DataFrame另外一种数据形式是嵌套字典,被解释为:外层字典的键作为列,内层字典则作为行索引。

DataFrame的索引对象:

一般索引对象负责管理轴标签和其他元数据,在series和dataframe构建中,所用到的任何数组或者其他序列都会转换成一个index,且index不可修改(immutable)

index的方法和属性如下:

 

     方法                        属性                    
append  连接另一个index对象,产生一个新的index
diff 计算差集,并得到一个index
intersection 计算交集
union 计算并集
isin 计算指示值是否都在参数集合的布尔型数组
delete 删除索引i处的元素,并得到新的index
drop 删除值,
insert 将元素插入索引i处,
is_monotonic 当各元素均>=前一个元素时,返回true
is_unique 当index没有重复值是,返回true
unique 计算index中唯一值

 

3、基本功能

①重新索引 reindex

有时候在重新索引中,我们需要做一些插值处理 method,常见的method选项有

ffill---向前填充值,   pad---向前搬运

bfill---向后填充,   backfill----向后搬运

obj1 = pd.Series(['blue','yellow','red'],index = [1,3,5])
obj1.reindex(range(7),method = 'pad')
返回为
0       NaN
1      blue
2      blue
3    yellow
4    yellow
5       red
6       red
dtype: object

而在DataFrame中,reindex既可以修改行索引,列索引,还可以两个都修改。默认索引行

import numpy as np
import pandas as pd
frame = pd.DataFrame(np.arange(9).reshape((3,3)),index = ['a','b','c'],columns = ['X','Y','Z'])
frame
返回为
     X    Y    Z
a    0    1    2
b    3    4    5
c    6    7    8
修改行索引为
frame2 = frame.reindex(['a','b','c','d'],method = 'ffill')
frame2
返回为
     X    Y    Z
a    0    1    2
b    3    4    5
c    6    7    8
d    6    7    8

行列同时修改为

DaXie = ['W','X','Z']
frame.reindex(index = ['a','b','c','d'],method = 'ffill',columns = DaXie)
返回为
        W    X    Z
a    NaN    0    2
b    NaN    3    5
c    NaN    6    8
d    NaN    6    8

其实利用ix的标签索引功能,会让程序更加简洁

frame.ix[['a','b','c','d'],DaXie]
返回为
      W       X     Z
a    NaN    0.0    2.0
b    NaN    3.0    5.0
c    NaN    6.0    8.0
d    NaN    NaN    NaN

②丢弃轴上的项 drop,默认丢弃行

frame = pd.DataFrame(np.arange(9).reshape((3,3)),index = ['a','b','c'],columns = ['X','Y','Z'])
frame.drop('X',axis = 1)
返回为
     Y    Z
a    1    2
b    4    5
c    7    8

③、数据运算和对齐

pandas的运算只针对索引的对象,当对象相加时,如果有不同的索引时,则结果的索引就是该索引的并集。

s1 = pd.Series([2.8,-1.3,4.5,-6.5],index = ['a','c','d','f'])
s2 = pd.Series([1.6,6.3,2.5,4.5,6.7],index = ['c','b','a','e','a'])
s1 + s2
返回为
a    5.3
a    9.5
b    NaN
c    0.3
d    NaN
e    NaN
f    NaN

而在DataFrame中,对齐操作会同时发生在行和列上

对于一些NaN值,我们通常会使用fill_value来填充值

df1 = pd.DataFrame(np.arange(12).reshape(4,3),columns = list('abc'))
df2 = pd.DataFrame(np.arange(20).reshape(5,4),columns = list('bcde'))
df1.add(df2,fill_value = 0)
返回为
        a    b      c      d         e
0    0.0    1.0     3.0      2.0    3.0
1    3.0    8.0     10.0     6.0    7.0
2    6.0    15.0    17.0    10.0    11.0
3    9.0    22.0    24.0    14.0    15.0
4    NaN    16.0    17.0    18.0    19.0

同样的,当对series或dataframe重新索引时,也可以指定填充值

df1.reindex(columns = df2.columns,fill_value = 0)
返回为

       b    c    d    e
0    1    2    0    0
1    4    5    0    0
2    7    8    0    0
3    10    11    0    0

④、DataFrame 和 Series 之间的运算

广播:不同形状的数组之间的的算数运算的执行方式。

frame = pd.DataFrame(np.arange(9).reshape((3,3)),index = ['a','b','c'],columns = ['X','Y','Z'])
series = frame.ix[1]
frame - series
返回为
      X    Y    Z
a    -3    -3    -3
b    0    0    0
c    3    3    3

两者之间的运算会将Series的索引匹配到DataFrame的列,然后沿着行一直向下广播

add 加法
sub 减法
mul 乘法
div 除法

4、函数应用和映射

DataFrame的apply可以实现将函数应用到由各行或各列形成的一维数组上。

 

frame = pd.DataFrame(np.random.randn(4,3),columns = list('abc'),index = ['W','X','Y','Z'])
返回为
                a          b          c
W    0.417966    -1.034917    2.980040
X    0.254318    -1.566016    -0.675548
Y    0.612923    -1.983434    -0.902464
Z    -1.094007    -1.674415    -2.307312

f = lambda x: x.max() - x.min()
frame.apply(f)
返回为
a    1.706930
b    0.948516
c    5.287352
frame.apply(f,axis = 1

 

apply还可以返回多个值组成的Series

def f(x):
    return pd.Series([x.min(),x.max()],index = ['min','max'])
frame.apply(f)
返回为
           a            b         c
min    -1.094007    -1.983434    -2.307312
max    0.612923    -1.034917    2.980040

也可以使用applymap得到frame的各个浮点值的格式化字符:

format = lambda x: '%.2f' % x
frame.applymap(format)
返回为
      a       b           c
W    0.42    -1.03    2.98
X    0.25    -1.57    -0.68
Y    0.61    -1.98    -0.90
Z    -1.09   -1.67    -2.31

5、排序和排名

排序一般用sort_index,将返回一个已排序的新对象:

obj = pd.Series(range(5),index = ['d','c','b','e','a'])
obj.sort_index
返回为
c    1
b    2
e    3
a    4

在DataFrame中,sort_index()可以有很多种排序方式

①     .sort_index() 按行排列

②     .sort_index(axis = 1) 按列排列

③     默认升序排序,降序 ascending = False

④     在DataFrame中,使用by能够将一个或多个列的值进行排序

frame = pd.DataFrame({'c':[3,-5,2,7],'a':[2,1,0,1]})
frame.sort_index(by = 'a')
返回为
     c    a
2    2    0
1    -5    1
3    7    1
0    3    2

 

⑤     对Series排序时,使用order 就可以,缺失值会被默认放到Series的末尾

Rank

rank 通过“为各组分配一个平均排名”来破坏这组数据的平均关系

obj = pd.Series([5,-9,3,2.5])
obj.rank()
返回为
0    4.0
1    1.0
2    3.0
3    2.0

另一种方法是,根据值在原数据中出现的顺序给出排名

obj.rank(method = 'first')
obj
返回为
0    5.0
1   -9.0
2    3.0
3    2.5

降序为,obj.rank(ascending = False, method = 'max')

排名中用于破坏平级关系的method选项有:

average ,默认项,值分配平均排名

min,  最小排名

max, 最大排名

first,顺序排名

    如果某个索引对应多个值,则返回一个Series;当对应单个值时,则返回一个标量值。

6、汇总和计算描述统计

 

df = pd.DataFrame([[2.3,1],[np.nan,2.5],
                   [np.nan,np.nan],[0.8,-2.3]],index = ['a','b','c','d'],columns = ['one','two'])
df.sum(axis = 1)
返回为
a    3.3
b    2.5
c    0.0
d   -1.5
NA值会被自动排除,当引入skipna = False时,能够禁用该功能。
df.idxmax()#间接索引,最大值的索引,也有min
返回为
one    a
two    b
df.cumsum()#累积型
df.describe()#一次性产生多个统计汇总
返回为
one    two
count    2.00000    3.000000
mean    1.55000    0.400000
std    1.06066    2.455606
min    0.80000    -2.300000
25%    1.17500    -0.650000
50%    1.55000    1.000000
75%    1.92500    1.750000
max    2.30000    2.500000
对于非数值型,describe会产生另一种汇总统计
obj = pd.Series(['a','b','b','d']*3)
obj.describe()
返回为
count     12
unique     3
top        b
freq       6

在series中,用corr计算两个Series中重叠、非NA、按索引对齐的相关系数

                 ,用cov计算协方差

而DataFrame里面的corr和cov将以DataFrame形式返回矩阵,

    另外,dataframe中的corrwith返回一个相关系数值Series(针对各列计算)

唯一值、值计数

唯一值
obj = pd.Series(['b','c','a','b','d','c','b','a','d'])
uniques = obj.unique()
uniques
返回
array(['b', 'c', 'a', 'd'], dtype=object)
值计数
obj.value_counts()
返回为
b    3
c    2
a    2
d    2
isin--判断矢量化集合的成员资格
mask = obj.isin(['a','c'])
obj[mask]
返回为
1    c
2    a
5    c
7    a

 7、处理缺失数据

一些NA值处理的方法:

dropna -- 标签中是否存在缺失数据对轴进行过滤

fillna -- 用指定值,插值填充缺失数据

isnull -- 返回布尔值的对象

notnull -- isnull的否定值

     过滤

在Series中

from numpy import nan as NA
data = pd.Series([2,3.5,NA,7])
data.dropna()
返回为
0    2.0
1    3.5
3    7.0
或者
data[data.notnull()]

在DataFrame中,dropna默认丢弃任何有缺失值的行,当传入how = ‘all’只丢弃全为NA的行,当丢弃列传入axis=1

data = pd.DataFrame([[2.,3.,5.,6.],[NA,3.4,2.5],[NA,NA,NA,NA],[2.5,NA,3.4,NA]])
cleaned = data.dropna()
cleaned
返回为
        0    1    2    3
0    2.0    3.0    5.0    6.0

data.dropna(how = 'all')
返回为
        0    1    2    3
0    2.0    3.0    5.0    6.0
1    NaN    3.4    2.5    NaN
3    2.5    NaN    3.4    NaN

当涉及时间序列数据时,可以用thresh函数实现只留下一部分观测数据。

df = pd.DataFrame(np.random.randn(6,3))
df.ix[:3,1] = NA;df.ix[:2,3] =NA
df
返回
            0          1      2         3
0    0.635500    NaN    0.722100    NaN
1    0.357698    NaN    -0.026564    NaN
2    -1.786260    NaN    -0.233946    NaN
3    -0.072525    NaN    -0.760752    NaN
4    0.259237    -0.961763    1.049663    NaN
5    0.303433    0.893801    -0.756076    NaN

df.dropna(thresh =3)
返回
         0            1            2      3
4    0.259237    -0.961763    1.049663    NaN
5    0.303433    0.893801    -0.756076    NaN

     填充

既可以用具体值填充,也可以用字典形式填充,

df.fillna(1)

df.fillna({2:0.1,3:1})当对填充对现有对象就地修改时,只需 inplace = True

fillna还可以传入Series的平均值或中位数

data = pd.Series([1.,NA,3.5,NA,7])
data.fillna(data.sum())
返回
0     1.0
1    11.5
2     3.5
3    11.5
4     7.0

8、层次化索引

 层次化索引是指,能够以低纬度形式处理高纬度数据的一种方式,如下:


data = pd.Series(np.random.randn(10),index = [['a','a','a','b','b','c','c','c','d','d'],[1,2,3,4,5,6,7,8,9,10]])
data

返回为


a  1     0.416143
   2    -2.428242
   3     0.166570
b  4     1.124723
   5     0.752965
c  6    -0.563679
   7    -0.319499
   8    -0.943406
d  9     0.185833
   10    1.583854
带有MultiIndex索引的Series,可以有多种选取子集的操作,
data[:,
1]
返回为
a    0.416143

层次化索引在数据重塑,透视表的生成中广泛应用

     可以通过unstack方法安排到DataFrame中:

data.unstack()
返回为
  1    2    3    4    5    6    7    8    9    10
a    0.416143    -2.428242    0.16657    NaN    NaN    NaN    NaN    NaN    NaN    NaN
b    NaN    NaN    NaN    1.124723    0.752965    NaN    NaN    NaN    NaN    NaN
c    NaN    NaN    NaN    NaN    NaN    -0.563679    -0.319499    -0.943406    NaN    NaN
d    NaN    NaN    NaN    NaN    NaN    NaN    NaN    NaN    0.185833    1.583854

unstack的逆运算是stack,

data.unstack().stack()

而在dataframe中,每一个轴都可以进行分层索引

frame = pd.DataFrame(np.arange(12).reshape(4,3),
                     index = [['a','a','b','b'],[1,2,1,2]],
                     columns = [['Pen','Pen','Pencil'],['big','small','big']])
frame
返回为
  
        Pen            Pencil
        big    small     big
a    1    0    1    2
        2    3    4    5
b    1    6    7    8
        2    9    10    11
各层命名如下
frame.index.names = ['price 1','price 2']
frame.columns.names = ['Species','Size']
frame
返回为
Species Pen Pencil Size big small big price
1 price 2 a 1 0 1 2 2 3 4 5 b 1 6 7 8 2 9 10 11

选列就可以用列分组完成:

frame['Pen']
返回为
Size big    small
price 1    price 2        
a    1    0    1
2    3    4
b    1    6    7
2    9    10

重排、分级 顺序

调整轴上各级顺序时,我们引用swaplevel函数,可以接受两个级别编号或名称,并返回互换级别的新对象

frame.swaplevel('price 1','price 2')
返回为
    Species    Pen    Pencil
Size    big    small    big
price 2    price 1            
1    a    0    1    2
2    a    3    4    5
1    b    6    7    8
2    b    9    10    11

sortlevel函数能根据单个级别中的值对数据进行排序

frame.sortlevel(1)
返回
    Species    Pen    Pencil
Size    big    small    big
price 1    price 2            
a    1    0    1    2
b    1    6    7    8
a    2    3    4    5
b    2    9    10    11


frame.swaplevel('price 1','price 2').sortlevel(1)
返回
Species    Pen    Pencil
Size    big    small    big
price 2    price 1            
1    a    0    1    2
2    a    3    4    5
1    b    6    7    8
2    b    9    10    11

使用DataFrame列

DataFrame中的set_index函数能将一个或多个列转换为行索引,并创建一个新的DataFrame

 

 

 

 

 

 

posted @ 2018-08-26 21:01  积水聚沙  阅读(247)  评论(0编辑  收藏  举报