《利用python进行数据分析》——5 pandas入门——读书笔记

《利用python进行数据分析》——5 pandas入门——读书笔记

1.pandas简介:

  1. Pandas是Python的一个数据分析包,该工具为解决数据分析任务而创建
  2. pandas是《利用python进行数据分析》后续内容的首选库。
  3. pandas含有使数据清洗和分析工作变得更快更简单的数据结构和操作工具
  4. Pandas是字典形式,基于NumPy创建,让NumPy为中心的应用变得更加简单
  5. Pandas纳入大量库和标准数据模型,提供高效的操作数据集所需的工具

pandas 约定俗成的导入方法如下:

In [1]: import pandas as pd

因为Series和DataFrame用的次数非常多,所以将其引入本地命名空间中会更方便:

In [2]: from pandas import Series, DataFrame

2.pandas的数据结构介绍:

两个主要数据结构:Series和DataFrame。

Series 和 DataFrame 分别对应于一维的序列和二维的表结构。


2.1Series

Series是一种类似于一维数组的对象,它由⼀组数据(各种NumPy数据类型)以及一组与之相关的数据标签(即索引)组
成。

2.1.1.构造Series

可以看做一个定长的有序字典。基本任意的一维数据都可以用来构造 Series 对象:
仅由一组数据即可产生最简单的Series:

In [11]: obj = pd.Series([4, 7, -5, 3])

In [12]: obj

Out[12]:
0 4
1 7
2 -5
3 3
dtype: int64

2.1.2.Series 的values和index属性

Series的字符串表现形式为:索引在左边,值在右边。由于我们没有为数据指定索引,于是会自动创建一个0到N-1(N为数据的
长度)的整数型索引。你可以通过Series 的values和index属性获取其数组表示形式和索引对象:

In [13]: obj.values

Out[13]: array([ 4, 7, -5, 3])

In [14]: obj.index # like range(4)

Out[14]: RangeIndex(start=0, stop=4, step=1)

2.1.3.用字典来创建Series

如果数据被存放在一个Python字典中,也可以直接通过这个字典来创建Series:

In [26]: sdata = {'Ohio': 35000, 'Texas': 71000, 'Oregon': 16000, 'Texas': 71000, 'Utah': 5000}

In [27]: obj3 = pd.Series(sdata)

In [28]: obj3

Out[28]:
Ohio 35000
Oregon 16000
Texas 71000
Utah 5000
dtype: int64

如果只传入一个字典,则结果Series中的索引就是原字典的键(有序排列)。你可以传入排好序的字典的键以改变顺序:

In [29]: states = ['California', 'Ohio', 'Oregon', 'Texas']

In [30]: obj4 = pd.Series(sdata, index=states)

In [31]: obj4

Out[31]:
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64

在这个例子中,sdata中跟states索引相匹配的那3个值会被找出来并放到相应的位置上,但由于"California"所对应的sdata值找不到,所以其结果就为NaN(即“非数字”(not a number),在pandas中,它用于表示缺失或NA值)。因为‘Utah’不在states中,它被从结果中除去。

2.1.4.检测缺失数据

我将使用缺失(missing)或NA表示缺失数据。pandas的isnull和notnull函数可用于检测缺失数据:

In [32]: pd.isnull(obj4)

Out[32]:
California True
Ohio False
Oregon False
Texas False
dtype: bool

In [33]: pd.notnull(obj4)

Out[33]:
California False
Ohio True
Oregon True
Texas True
dtype: bool

Series也有类似检测缺失数据的实例方法:

In [34]: obj4.isnull()

Out[34]:
California True
Ohio False
Oregon False
Texas False
dtype: bool

2.1.5.根据运算的索引标签自动对齐数据

对于许多应用而言,Series最重要的一个功能是,它会根据运算的索引标签自动对齐数据:

In [35]: obj3

Out[35]:
Ohio 35000
Oregon 16000
Texas 71000
Utah 5000
dtype: int64

In [36]: obj4

Out[36]:
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
dtype: float64

In [37]: obj3 + obj4

Out[37]:
California NaN
Ohio 70000.0
Oregon 32000.0
Texas 142000.0
Utah NaN
dtype: float64

2.1.6.name属性

Series对象本身及其索引都有一个name属性,该属性跟pandas其他的关键功能关系非常密切:

In [38]: obj4.name = 'population'

In [39]: obj4.index.name = 'state'

In [40]: obj4

Out[40]:
state
California NaN
Ohio 35000.0
Oregon 16000.0
Texas 71000.0
Name: population, dtype: float64

2.1.7.修改索引

Series的索引可以通过赋值的方式就地修改:

In [41]: obj

Out[41]:
0 4
1 7
2 -5
3 3
dtype: int64

In [42]: obj.index = ['Bob', 'Steve', 'Jeff', 'Ryan']

In [43]: obj

Out[43]:
Bob 4
Steve 7
Jeff -5
Ryan 3
dtype: int64

2.2DataFrame

  1. DataFrame 是一个表格型的数据结构,它含有一组有序的列(类似于 index),每列可以是不同的值类型(可以是数值、字符串、布尔值等)。
  2. DataFrame既有行索引也有列索引,基本上可以把 DataFrame 看成是共享同一个索引 的 Series 的集合。
  3. DataFrame中的数据是以一个或多个二维块存放的(而不是列表、字典或别的一维数据结构)
  4. 虽然DataFrame是以二维结构保存数据的,但仍然可以轻松地将其表示为更高维度的数据(层次化索引的表格型结构,这是pandas中许多高级数据处理功能的关键要素)    

2.2.1.构造DataFrame

建DataFrame的办法有很多,最常用的一种是直接传入一个由等长列表或NumPy数组组成的字典:

结果DataFrame会自动加上索引(跟Series一样),且全部列会被有序排列:

In [43]: data = {'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada', 'year': [2000, 2001, 2002, 2001, 2002, 2003],'pop': [1.5, 1.7, 3.6, 2.4, 2.9, 3.2]}

In [44]: frame = pd.DataFrame(data)

In [45]: frame

Out[45]:
  pop state year
0 1.5 Ohio 2000
1 1.7 Ohio 2001
2 3.6 Ohio 2002
3 2.4 Nevada 2001
4 2.9 Nevada 2002
5 3.2 Nevada 2003

2.2.2.head方法

对于特别大的DataFrame(起码>5行),head方法会选取前五行,head(3)会选取前三行

In [46]: frame.head()

Out[46]:
pop state year
0 1.5 Ohio 2000
1 1.7 Ohio 2001
2 3.6 Ohio 2002
3 2.4 Nevada 2001
4 2.9 Nevada 2002

2.2.3.获取指定列

如果指定了列序列,则DataFrame的列就会按照指定顺序进行排列:

如果传入的列在数据中找不到,就会在结果中产生缺失值:

In [47]: pd.DataFrame(data, columns=['year', 'state', 'pop'])

Out[47]:
year state pop
0 2000 Ohio 1.5
1 2001 Ohio 1.7
2 2002 Ohio 3.6
3 2001 Nevada 2.4
4 2002 Nevada 2.9
5 2003 Nevada 3.2

通过类似字典标记的方式或属性的方式,可以将DataFrame的列获取为一个Series:

返回的Series拥有原DataFrame相同的索引,且其name属性也已经被相应地设置好了。

In [51]: frame2['state']

Out[51]:
one Ohio
two Ohio
three Ohio
four Nevada
five Nevada
six Nevada
Name: state, dtype: object

In [52]: frame2.year

Out[52]:
one 2000
two 2001
three 2002
four 2001
five 2002
six 2003
Name: year, dtype: int64

2.2.4.用loc属性获取行

行也可以通过位置或名称的方式进行获取,比如用loc属性:

In [53]: frame2.loc['three']

Out[53]:
year 2002
state Ohio
pop 3.6
debt NaN
Name: three, dtype: object

2.2.5.修改列

列可以通过赋值的方式进行修改

In [54]: frame2['debt'] = 16.5

In [55]: frame2

Out[55]:
year state pop debt
one 2000 Ohio 1.5 16.5
two 2001 Ohio 1.7 16.5
three 2002 Ohio 3.6 16.5
four 2001 Nevada 2.4 16.5
five 2002 Nevada 2.9 16.5
six 2003 Nevada 3.2 16.5

In [56]: frame2['debt'] = np.arange(6.)

In [57]: frame2

Out[57]:
year state pop debt
one 2000 Ohio 1.5 0.0
two 2001 Ohio 1.7 1.0
three 2002 Ohio 3.6 2.0
four 2001 Nevada 2.4 3.0
five 2002 Nevada 2.9 4.0
six 2003 Nevada 3.2 5.0

2.2.6.嵌套字典传给DataFrame

嵌套字典传给DataFrame,pandas就会被解释为:外层字典的键作为列,内层键则作为行索引:

In [65]: pop = {'Nevada': {2001: 2.4, 2002: 2.9},'Ohio': {2000: 1.5, 2001: 1.7, 2002: 3.6}}

In [66]: frame3 = pd.DataFrame(pop)

In [67]: frame3

Out[67]:
  Nevada Ohio
2000 NaN 1.5
2001 2.4 1.7
2002 2.9 3.6

2.2.7.T方法转置

T方法对DataFrame进行转置(交换行和列):

In [68]: frame3.T

Out[68]:
2000 2001 2002
Nevada NaN 2.4 2.9
Ohio 1.5 1.7 3.6

3.汇总和计算描述统计

看一个简单的DataFrame:

In [230]: df = pd.DataFrame([[1.4, np.nan], [7.1, -4.5],
.....: [np.nan, np.nan], [0.75, -1.3]],
.....: index=['a', 'b', 'c', 'd'],
.....: columns=['one', 'two'])

In [231]: df

Out[231]:
  one two
a 1.40 NaN
b 7.10 -4.5
c NaN NaN
d 0.75 -1.3

3.1 sum方法:返回一个含有所有列的和的Series

调用DataFrame的sum方法将会返回一个含有所有列的和的Series:(所有列的和)

In [232]: df.sum()

Out[232]:
one 9.25
two -5.80
dtype: float64

传入axis='columns'或axis=1将会按行进行求和运算:(所有行的和)

In [233]: df.sum(axis=1)

Out[233]:
a 1.40
b 2.60
c NaN
d -0.55

3.2 相关系数与协方差:

计算DataFrame列与列的相关系数和协方差(文末有相关系数和协方差的简介)

    a = np.arange(1,10).reshape(3,3)
    data = DataFrame(a,index=["a","b","c"],columns=["one","two","three"])
    print(data)
    '''
       one  two  three
    a    1    2      3
    b    4    5      6
    c    7    8      9
    '''
    #计算第一列和第二列的相关系数
    print(data.one.corr(data.two))
    #1.0
    #返回一个相关系数矩阵
    print(data.corr())
    '''
           one  two  three
    one    1.0  1.0    1.0
    two    1.0  1.0    1.0
    three  1.0  1.0    1.0
    '''
    #计算第一列和第二列的协方差
    print(data.one.cov(data.two))
    #9.0
    #返回一个协方差矩阵
    print(data.cov())
    '''
           one  two  three
    one    9.0  9.0    9.0
    two    9.0  9.0    9.0
    three  9.0  9.0    9.0
    '''

计算DataFrame与列或者Series的相关系数

    a = np.arange(1,10).reshape(3,3)
    data = DataFrame(a,index=["a","b","c"],columns=["one","two","three"])
    print(data)
    '''
       one  two  three
    a    1    2      3
    b    4    5      6
    c    7    8      9
    '''
    #计算data与第三列的相关系数
    print(data.corrwith(data.three))
    '''
    one      1.0
    two      1.0
    three    1.0
    '''
    #计算data与Series的相关系数
    #在定义Series的时候,索引一定要去DataFrame的索引一样
    s = Series([5,3,1],index=["a","b","c"])
    print(data.corrwith(s))
    '''
    one     -1.0
    two     -1.0
    three   -1.0
    '''

注意:在使用DataFrame或Series在计算相关系数或者协方差的时候,都会计算索引重叠的、非NA的、按照索引对齐原则,对于无法对齐的索引会使用NA值进行填充
在使用DataFrame与指定的行或列或Series计算协方差和相关系数的时候,默认都是与DataFrame的列进行计算,如果想要计算行,设置axis参数为1即可。
转自:https://blog.csdn.net/chang995196962/article/details/88887264

3.3 唯一值、值计数以及成员资格

unique():返回Series中的唯一值数

In [251]: obj = pd.Series(['c', 'a', 'd', 'a', 'a', 'b', 'b','c','c',])

In [252]: uniques = obj.unique()

In [253]: uniques

Out[253]: array(['c', 'a', 'd', 'b'], dtype=object)

value_counts():计算一个Series中各值出现的频率

In [254]: obj.value_counts()
Out[254]:
c 3
a 3
b 2
d 1
dtype: int64

isin():用于判断矢量化集合的成员资格

可用于过滤Series中或DataFrame列中数据的子集:

In [256]: obj

Out[256]:
0 c
1 a
2 d
3 a
4 a
5 b
6 b
7 c
8 c
dtype: object

In [257]: mask = obj.isin(['b', 'c'])

In [258]: mask
Out[258]:
0 True
1 False
2 False
3 False
4 False
5 True
6 True
7 True
8 True
dtype: bool

In [259]: obj[mask]

Out[259]:
0 c
5 b
6 b
7 c
8 c
dtype: object

alue_counts():是一种查看表格某列中有多少个不同值的快捷方法,并计算每个不同值有在该列中有多少重复值。

value_counts()是Series拥有的方法,一般在DataFrame中使用时,需要指定对哪一列或行使用,该函数返回的也是Series类型,且index为该列的不同值,values为不同值的个数

结果中的行标签是所有列的唯一值。这些值是每个列中这些值的相应计数

In [263]: data = pd.DataFrame({'Qu1': [1, 3, 4, 3, 4],'Qu2': [2, 3, 1, 2, 3],'Qu3': [1, 5, 2, 4, 4]})

In [264]: data

Out[264]:
    Qu1  Qu2  Qu3
0    1    2    1
1    3    3    5
2    4    1    2
3    3    2    4
4    4    3    4

In [265]: result = data.apply(pd.value_counts).fillna(0)

In [266]: result

Out[266]:
   Qu1  Qu2  Qu3
1  1.0  1.0  1.0
2  0.0  2.0  1.0
3  2.0  2.0  0.0
4  2.0  0.0  2.0
5  0.0  0.0  1.0

4.pandas常用函数

数据预处理

df.duplicated() 返回各行是否是上一行的重复行
df.drop_duplicates() 删除重复行,如果需要按照列过滤,参数选填['col1', 'col2',...]
df.fillna(0) 用实数0填充na
df.dropna() axis=0|1 0-index 1-column
how='all'|'any' all-全部是NA才删 any-只要有NA就全删
del df['col1'] 直接删除某一列 
df.drop(['col1',...], aixs=1) 删除指定列,也可以删除行 
df.column = col_lst 重新制定列名
df.rename(index={'row1':'A'}, 重命名索引名和列名
columns={'col1':'A1'}) 
df.replace(dict) 替换df值,前后值可以用字典表,{1:‘A', '2':'B'}

def get_digits(str):
m = re.match(r'(\d+(\.\d+)?)', str.decode('utf-8'))
if m is not None: 
return float(m.groups()[0])
else:
return 0
df.apply(get_digits) DataFrame.apply,只获取小数部分,可以选定某一列或行
df['col1'].map(func) Series.map,只对列进行函数转换

pd.merge(df1, df2, on='col1',
how='inner',sort=True) 合并两个DataFrame,按照共有的某列做内连接(交集),outter为外连接(并集),结果排序

pd.merge(df1, df2, left_on='col1',
right_on='col2') df1 df2没有公共列名,所以合并需指定两边的参考列


pd.concat([sr1, sr2, sr3,...], axis=0) 多个Series堆叠成多行,结果仍然是一个Series
pd.concat([sr1, sr2, sr3,...], axis=1) 多个Series组合成多行多列,结果是一个DataFrame,索引取并集,没有交集的位置填入缺省值NaN

df1.combine_first(df2) 用df2的数据补充df1的缺省值NaN,如果df2有更多行,也一并补上

df.stack() 列旋转成行,也就是列名变为索引名,原索引变成多层索引,结果是具有多层索引的Series,实际上是把数据集拉长

df.unstack() 将含有多层索引的Series转换为DataFrame,实际上是把数据集压扁,如果某一列具有较少类别,那么把这些类别拉出来作为列
df.pivot() 实际上是unstack的应用,把数据集压扁

pd.get_dummies(df['col1'], prefix='key') 某列含有有限个值,且这些值一般是字符串,例如国家,借鉴位图的思想,可以把k个国家这一列量化成k列,每列用0、1表示

数据筛选

df.columns 列名,返回Index类型的列的集合
df.index 索引名,返回Index类型的索引的集合
df.shape 返回tuple,行x列
df.head(n=N) 返回前N条
df.tail(n=M) 返回后M条
df.values 值的二维数组,以numpy.ndarray对象返回
df.index DataFrame的索引,索引不可以直接赋值修改
df.reindex(index=['row1', 'row2',...]
columns=['col1', 'col2',...]) 根据新索引重新排序
df[m:n] 切片,选取m~n-1行
df[df['col1'] > 1] 选取满足条件的行
df.query('col1 > 1') 选取满足条件的行
df.query('col1==[v1,v2,...]') 
df.ix[:,'col1'] 选取某一列
df.ix['row1', 'col2'] 选取某一元素
df.ix[:,:'col2'] 切片选取某一列之前(包括col2)的所有列
df.loc[m:n] 获取从m~n行(推荐)
df.iloc[m:n] 获取从m~n-1行
df.loc[m:n-1,'col1':'coln'] 获取从m~n行的col1~coln列


sr=df['col'] 取某一列,返回Series
sr.values Series的值,以numpy.ndarray对象返回
sr.index Series的索引,以index对象返回

数据运算与排序

df.T DataFrame转置
df1 + df2 按照索引和列相加,得到并集,NaN填充
df1.add(df2, fill_value=0) 用其他值填充
df1.add/sub//mul/div 四则运算的方法
df - sr DataFrame的所有行同时减去Series
df * N 所有元素乘以N
df.add(sr, axis=0) DataFrame的所有列同时减去Series


sr.order() Series升序排列
df.sort_index(aixs=0, ascending=True) 按行索引升序
df.sort_index(by=['col1', 'col2'...]) 按指定列优先排序
df.rank() 计算排名rank值

数学统计

sr.unique Series去重
sr.value_counts() Series统计频率,并从大到小排序,DataFrame没有这个方法
sr.describe() 返回基本统计量和分位数

df.describe() 按各列返回基本统计量和分位数
df.count() 求非NA值得数量
df.max() 求最大值
df.min() 求最大值
df.sum(axis=0) 按各列求和
df.mean() 按各列求平均值
df.median() 求中位数
df.var() 求方差
df.std() 求标准差
df.mad() 根据平均值计算平均绝对利差
df.cumsum() 求累计和
sr1.corr(sr2) 求相关系数
df.cov() 求协方差矩阵
df1.corrwith(df2) 求相关系数

pd.cut(array1, bins) 求一维数据的区间分布
pd.qcut(array1, 4) 按指定分位数进行区间划分,4可以替换成自定义的分位数列表

df['col1'].groupby(df['col2']) 列1按照列2分组,即列2作为key
df.groupby('col1') DataFrame按照列1分组
grouped.aggreagte(func) 分组后根据传入函数来聚合
grouped.aggregate([f1, f2,...]) 根据多个函数聚合,表现成多列,函数名为列名
grouped.aggregate([('f1_name', f1), ('f2_name', f2)]) 重命名聚合后的列名
grouped.aggregate({'col1':f1, 'col2':f2,...}) 对不同的列应用不同函数的聚合,函数也可以是多个


df.pivot_table(['col1', 'col2'], 
rows=['row1', 'row2'], 
aggfunc=[np.mean, np.sum]
fill_value=0,
margins=True) 根据row1, row2对col1, col2做分组聚合,聚合方法可以指定多种,并用指定值替换缺省值 

pd.crosstab(df['col1'], df['col2']) 交叉表,计算分组的频率

5.协方差与相关系数

协方差

简单理解
定义两个变量变量a,和变量b
变量a增大,变量b也增大说明两个变量是同向的,协方差为正
变量a变大,变量b变小说明两个变量反向的,协方差为负
协方差代表这两个数值a和b之间的同向或者反向程度

公式

比如,一个西瓜甜度和它所在的海拔位置是否存在练习。按照以上公式x为西瓜甜度,y为海拔高度,代入公式计算,如果结果为负值,就说明两者负相关,海拔越低西瓜越甜,如果正相关,则海拔越高西瓜越甜,如果为0,则海拔和西瓜甜度没有关系。
协方差矩阵
当然西瓜的例子属于二维的问题,实际问题往往是多维度,在机器学习中往往是用矩阵(多维数组)来计算。
为此,我们可以利用下面公式来哦计算。以三维为例子:

相关系数

公式

其中:var(x)为x的方差,var(y)为y的方差
相关系数意义
Corr(X,Y)=1的时候,说明两个随机变量完全正相关,即满足Y=aX+b,a>0
Corr(X,Y)=1,两个随机变量相同
Corr(X,Y)=-1的时候,说明两个随机变量完全负相关,即满足Y=-aX+b,a>0
0<| Corr(X,Y)|<1的时候,说明两个随机变量具有一定程度的线性关系。
 

发布了15 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/baidu_28660921/article/details/104315973