Python数据分析基础笔记之Pandas基础

Pandas入门(实战)


Python Data Analysis Library pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Python Data Analysis Library 或 pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之一。

同时pandas还具备以下的功能: 

● 具备按轴自动或显式数据对齐功能的数据结构。这可以防止许多由于数据未对齐以及来自不同数据源的数据而导致的常见错误

● 集成时间序列功能

● 即能处理时间序列数据也能处理非时间序列数据的数据结构

● 数学运算和约简可以根据不同的元数据执行

● 灵活处理缺失数据

● 合并及其他出现在常见数据库中的关系型运算



Pandas的数据结构介绍

代码运行环境:Pycharm,py3.6,numpy,pandas

Pandas主要的两个数据结构:SeriesDataFrame。接下来对Series与DataFrame进行介绍。


Series

Series是一种类似于一维数组的对象,它由一组数据(各种Numpy数据类型)以及一组与之相关的数据标签(即索引)组成。仅由一组数据即可产生最简单的Series

in:

import pandas as pd
from pandas import Series,DataFrame

obj  = Series([1,2,3,4,5])

print(obj)

out:

0    1
1    2
2    3
3    4
4    5
dtype: int64


通过pandas导入Series和DataFrame,且Series的字符串表现形式为:左边为索引,右边为值。由于索引没有进行定义,series会自动创建一个0到N-1的整型索引。可以通过Series的values和index属性获取其数组表示形式和索引对象:

in:

print('obj.values:',obj.values,'\nobj.index:',obj.index)

out:

obj.values: [1 2 3 4 5] 
obj.index: RangeIndex(start=0, stop=5, step=1)


通常会通过所创建的Series对index进行赋值,以方便对每行进行标记。

in:

obj2 = Series([1,2,3,4,5],index = ['a','b','c','d','e'])
print(obj2)

out:

a    1
b    2
c    3
d    4
e    5
dtype: int64


与普通的Numpy的数组相比,可以通过索引的方式选取Series中的单个或一组值:

in:

obj2['d'] = 6 #令第4个元素的值为6
print("obj2['a']",obj2['a'],"\nobj2['d']",obj2['d'],"\nobj2['c','a','d']",obj2[['c','a','d']])

out:

obj2['a']: 1 
obj2['d']: 6 
obj2['c','a','d']: c    3
                   a    1
                   d    6


Numpy数组运算(如根据布尔型数据进行过滤、标量乘法、应用数学函数等)都会保留索引和值之间的链接:

in:

print('obj2[obj2>3]:',obj2[obj2>=3])

print('obj2*2:',obj2*2)

print('np.exp(obj2):',np.exp(obj2))

out:

obj2[obj2>3]: c    3
              d    6
              e    5
dtype: int64
obj2*2: a     2
        b     4
        c     6
        d    12
        e    10
dtype: int64
np.exp(obj2): a      2.718282
              b      7.389056
              c     20.085537
              d    403.428793
              e    148.413159
dtype: float64


还可以将Series看成是一个定长的有序字典,因为它是索引值到数据值的一个映射。它可以用于在许多原本需要字典参数的函数中

in:

print('b' in obj2)

print('z' in obj2)
out:
True
False


对于Python中的字典来说,Series可以支持直接通过字典来创建Series

in:

sdata  = {'Eirc':520,'Rick':1314,'Morty':250}

obj3 = Series(sdata)

print('obj3:',obj3)
out:
obj3: Eirc      520
      Morty     250
      Rick     1314
dtype: int64

 

如果只传入一个字典的话在Series的值中索引为原字典的键值(有序排列)

对于找不到的值NAN,pandas的isnull和notnull函数可以用于检测缺失数据:

in:

obj4 = Series([1,2,3,3,4])
obj4[3] = np.nan#np.nan可以用来创造缺失值
print('obj4:',obj4)
print('缺失值查找:',pd.isnull(obj4))

out:

obj4: 0    1.0
      1    2.0
      2    3.0
      3    NaN
      4    4.0
dtype: float64
缺失值查找: 0    False
            1    False
            2    False
            3     True
            4    False
dtype: bool


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

in:

obj4.name = 'Eric'
obj4.index.name = 'Rick'
print(obj4)

out:

Rick
0    1.0
1    2.0
2    3.0
3    NaN
4    4.0
Name: Eric, dtype: float64


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

in:

obj4.index =['Eirc','Bob','Rick','Morty','Tom']
print(obj4)

out:

Eirc     1.0
Bob      2.0
Rick     3.0
Morty    NaN
Tom      4.0
Name: Eric, dtype: float64

DataFrame

DataFrame 是一个表格型的数据结构,它含有一组有序的列,每列可以使不同的值类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,它可以被看做由Series组成的字典(共同用一个索引)。跟其他类似的数据结构相比(R中的data.frame),DataFrame中面向行和面向列的操作基本上是平衡的。在DataFrame中的数据时以一个或多个二维块进行存放的(而不是列表、字典或别的一维数据结构)。DataFrame是以二维结构保存数据的,但是可以仍然可以轻松地将其表示为更高维度的数据。


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

in:

data = {'state':['Ohio','Ohio','China','Nevada','China'],
        'year':[2000,2018,2014,2002,1995],
        'pop':[1.5,6.7,4.6,1.7,1.1]}

frame = DataFrame(data)

print("DataFrame:",frame)
out:
DataFrame:    pop   state  year
           0  1.5    Ohio  2000
           1  6.7    Ohio  2018
           2  4.6   China  2014
           3  1.7  Nevada  2002
           4  1.1   China  1995
结果DataFrame会自动加上索引。


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

in:

print(DataFrame(data,columns=['year','state','pop']))
out:
year   state  pop
0  2000    Ohio  1.5
1  2018    Ohio  6.7
2  2014   China  4.6
3  2002  Nevada  1.7
4  1995   China  1.1


跟Series一样,如果传入的列在数据中找不到,就会产生NaN值

in:

frame2 = DataFrame(data,columns=['year','state','pop','gdp'],index = ['a','b','c','d','e'])

print("frame2:",frame2)
out:
frame2:    year   state  pop  gdp
        a  2000    Ohio  1.5  NaN
        b  2018    Ohio  6.7  NaN
        c  2014   China  4.6  NaN
        d  2002  Nevada  1.7  NaN
        e  1995   China  1.1  NaN


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

in:

print("frame2['state']",frame2['state'],"\nframe2.year",frame2.year)
out:
frame2['state']: a      Ohio
                 b      Ohio
                 c     China
                 d    Nevada
                 e     China
Name: state, dtype: object 
frame2.year: a    2000
             b    2018
             c    2014
             d    2002
             e    1995
Name: year, dtype: int64


以上返回的Series拥有原DataFrame相同的索引,且其name属性也已经被相应的设置好了。行也可以通过位置或名称的方式进行获取,比如用索引字段ix:

in:

print(frame2.ix['d'])
out:
year       2002
state    Nevada
pop         1.7
gdp         NaN
Name: d, dtype: object


列值可以通过赋值的方式进行修改。比如给‘gdp’列赋值上一个标量值或一组值:

in:

frame2['gdp'] = 20

print(frame2)
out:
   year   state  pop  gdp
a  2000    Ohio  1.5   20
b  2018    Ohio  6.7   20
c  2014   China  4.6   20
d  2002  Nevada  1.7   20
e  1995   China  1.1   20

in:

frame2['gdp'] = np.arange(0,2.5,.5)#第一个是起始值,第二个是终止值,第三个是间隔值的大小可以用range(x1,x2)代替
print(frame2)

out:

   year   state  pop  gdp
a  2000    Ohio  1.5  0.0
b  2018    Ohio  6.7  0.5
c  2014   China  4.6  1.0
d  2002  Nevada  1.7  1.5
e  1995   China  1.1  2.0


将列表或数组赋值给某个列时,其长度必须跟DataFrame的长度相匹配。如果赋值的是一个Series,就会精确匹配DataFrame的索引,所有的空位都将被填上缺失值:

in:

values = Series([1.3,2,4],index = ['a','d','c'])

frame2.gdp = values#frame2.gdp = frame2['gdp']

print(frame2)

out:

   year   state  pop  gdp
a  2000    Ohio  1.5  1.3
b  2018    Ohio  6.7  NaN
c  2014   China  4.6  4.0
d  2002  Nevada  1.7  2.0
e  1995   China  1.1  NaN

为不存在的列赋值会创建出一个新列。关键字del可以用于删除列

in:

frame2['Feiyuqing'] = frame2.state == 'China'

print(frame2)

del frame2['Feiyuqing']

print(frame2)

out:

   year   state  pop  gdp  Feiyuqing
a  2000    Ohio  1.5  1.3      False
b  2018    Ohio  6.7  NaN      False
c  2014   China  4.6  4.0       True
d  2002  Nevada  1.7  2.0      False
e  1995   China  1.1  NaN       True
   year   state  pop  gdp
a  2000    Ohio  1.5  1.3
b  2018    Ohio  6.7  NaN
c  2014   China  4.6  4.0
d  2002  Nevada  1.7  2.0
e  1995   China  1.1  NaN

输入DataFrame构造器的数据
类型说明
二维ndarray数据矩阵,还可以传入行标和列标
由数组、列表或元组组成的字典每个序列会变成DataFrame的一列,所有序列的长度必须相同
Numpy的结构化/记录数组类似于"由数组组成的字典"
由Serie组成的字典每个Series会成为一列。如果没有显式指定索引,则各Series的索引会被合并成结果的行索引
由字典组成的字典各内层字典会成为一列。键会合并成结果的行索引,跟‘由Series组成的字典’的情况一样
字典或Series的列表各项将会成为DataFrame的一行。字典键或Series索引的并集将会成为DataFrame的列标
由列表或元组组成的列表类似于二维Ndarray
另一个DataFrame该DataFrame的索引将会被沿用,除非显示指定了其他索引
Numpy的MaskedArray类似于“二维Ndarray”的情况,掩码值在结果中DataFrame会变成NA/缺失值

索引对象


pandas的索引对象负责管理轴标签和其他元数据(比如轴名称等)。构建Series或DataFrame时,所用到的任何数据或其他序列的标签都会被转换成一个index:

in:

obj = Series(range(3),index = ['a','b','c'])

index = obj.index

print(index)

print(index[1:])
out:
Index(['a', 'b', 'c'], dtype='object')
Index(['b', 'c'], dtype='object')
tips:Index对象是不可修改的, e.g : index[1] = 'd'是错误的语法


pandas中主要的index对象
说明
Index最泛化的index对象,将轴标签表示为一个由Python对象组成的Numpy数组
int64Index针对整数的特殊index
MulitiIndex‘层次化’索引对象,表示单个轴上的多层索引,可以看做由元组组成的数组
DatatimeIndex存储纳秒级时间戳
PeriodIndex针对Period数据的特殊Index


每个索引都有一些方法和属性,它们可以用于设置逻辑并回答有关该索引所包含的数据的常见问题。具体见下表


Index的方法和属性
方法说明
append连接另一个Index对象,产生一个新的Index
diff

计算差集,并得到一个index

intersection计算交集
unicon计算并集
isin计算一个指示搁置是否都包含在参数集合中的布尔型函数
delete删除所有i处的元素,且得到新的index
drop

删除传入的值,且得到新的index

insert将元素插入到索引i出,且得到新的index
is_monotonic当各元素均大于等于前一个元素时,返回True
is_unique当index没有重复值时,返回True
unique计算index中的唯一值的数组



基本功能


重新索引


pandas对象的一个重要方法是reindex,其作用是是创建一个适应新索引的新对象。调用Series的reindex会根据新索引进行重排。如某个索引的值当前不存在于,则引入缺失值

in:

obj = Series([4.1,-2.1,3.5],index = ['d','a','c'])

obj2 = obj.reindex(['a','b','c','d','e'])

print('obj:',obj,'\nobj2:',obj2)

out:

obj: d    4.1
     a   -2.1
     c    3.5
dtype: float64 
obj2: a   -2.1
      b    NaN
      c    3.5
      d    4.1
      e    NaN
dtype: float64


reindex函数的参数
参数说明
index

用作索引的新序列。可以为index实例

,也可以是其他序列型的Python数据结构。index会被完全使用

method插值(填充)方式,ffill/pad(前向填充值),bfill/backfill(后向填充值)
fill_value在重新索引的过程中,需要引入缺失值时使用的替代值
limit前向或后向填充时的最多填充量
level在MultiIndex的指定级上匹配简单索引,否则选取其子集
copy默认为True,无论如何复制;False,则新旧相等就不复制

in:

obj = Series(range(3),index = ['a','b','c'])
obj2 = obj.reindex(['a','b','c','d','e','f','g'],fill_value=100)

print('obj2:',obj2)

out:

obj2: a     -2.1
      b    100.0
      c      3.5
      d      4.1
      e    100.0
      f    100.0
      g    100.0
dtype: float64


丢弃指定轴上的项

丢弃某条轴上的一个或多个项很简单,只要有一个索引数组或列表即可。由于需要执行一些数据整理和集合逻辑,所以drop方法返回的是一个指定轴上删除了指定值的新对象。

in:

obj = Series(np.arange(4),index = ['a','b','c','d'])
print('obj:',obj)
obj = obj.drop(['a','c'])
print("obj:",obj)

out:

obj: a    0
     b    1
     c    2
     d    3
dtype: int32
obj: b    1
     d    3
dtype: int32

对于DataFrame一样的可以进行删除任意轴上的索引值

in:

data = DataFrame(np.arange(12).reshape((3,4)),index = ['a','b','c'],columns = ['one','two','three','four'])

print("data.drop(['a','c']):",data.drop(['a','c']),"\ndata.drop(['one','three'],axis = 1):",data.drop(['one','three'],axis = 1))

out:

data.drop(['a','c']):    one  two  three  four
                     b    4    5      6     7 
data.drop(['one','three'],axis = 1):    two  four
                                    a    1     3
                                    b    5     7
                                    c    9    11


索引、选取和过滤

对于Series索引的工作方式类似于NumPy数组的索引,且对于DataFrame进行索引其实就是获取一个或者多个列,在对数据的操作中最根本的就是对数据进行选取、过滤来获得你所需要的数据集。为了在DataFrame上进行标签索引,我们将会引入专门的索引字段ix。其作用可以通过Numpy式的标记法以及轴标签选取行和列的子集。

in:

data = DataFrame(np.arange(16).reshape((4,4)),index = ['a','b','c','e'],columns = ['one','two','three','four'])

print('data:',data)
print("data[['four','one']]:",data[['four','one']])
print("data[:2]:",data[:2])
print("data[data<5]:",data[data<5])
print("data[:,:2]:",data.ix[2:4,:3])
print("data.ix[data.two>5,:3]:",data.ix[data.two>5,:3])
print("data.ix['a',['one','four']]:",data.ix['a',['one','four']])

out:

data:    one  two  three  four
a    0    1      2     3
b    4    5      6     7
c    8    9     10    11
e   12   13     14    15
data[['four','one']]:    four  one
a     3    0
b     7    4
c    11    8
e    15   12
data[:2]:    one  two  three  four
a    0    1      2     3
b    4    5      6     7
data[data<5]:    one  two  three  four
a  0.0  1.0    2.0   3.0
b  4.0  NaN    NaN   NaN
c  NaN  NaN    NaN   NaN
e  NaN  NaN    NaN   NaN
data[:,:2]:    one  two  three
c    8    9     10
e   12   13     14
data.ix[data.two>5,:3]:    one  two  three
c    8    9     10
e   12   13     14
data.ix['a',['one','four']]: one     0
four    3
Name: a, dtype: int32

也就是说,对pandas对象中的数据的选取和重排的方式很多。下表会简单的总结了针对DataFrame数据的大部分选取和重排方式。在使用层次化索引时还能用到一些别的方法。


DataFrame的索引选项
类型说明
obj[val]

选取DataFrame的单个列或一组列。在一些特殊情况下会比较便

利:布尔型数组,切片,布尔型DataFrame

obj.ix[val]选取DataFrame的单个行或一组行
obj.ix[:,val]选取单个列或列子集
obj.ix[var1,var2]同时选取行和列
reindex方法将一个或多个轴匹配到新索引
xs方法根据标签选取单列或单行、且返回一个Series
icol、irow方法根据整数位置选取单列或单行,且返回一个Series
get_value/set_value根据行标签和列标签选取单个值

函数应用和映射

在Pandas中的函数应用一般使用lambda的方式来建立简单的运算函数,也可以通过def的形式来定义函数,而要运用到DataFrame中则需要使用的apply方法,通过apply将函数应用到由各行或列所形成的一维数组上。

in:

data = DataFrame(np.arange(16).reshape((4,4)),index = ['a','b','c','e'],columns = ['one','two','three','four'])

f = lambda x:x.max() - x.min()

def f1(x):
       return x.max()-x.min()

print("data:",data)
print("data.apply(f):",data.apply(f))
print("data.apply(f,axis = 1):",data.apply(f,axis = 1))
print("data.apply(f1):",data.apply(f1))

out:

data:    one  two  three  four
     a    0    1      2     3
     b    4    5      6     7
     c    8    9     10    11
     e   12   13     14    15
data.apply(f): one      12
               two      12
               three    12
               four     12
dtype: int64
data.apply(f,axis = 1): a    3
                        b    3
                        c    3
                        e    3
dtype: int64
data.apply(f1): one      12
                two      12
                three    12
                four     12
dtype: int64


在Series中有一个可以运用到元素级上的函数叫做map,map方法可以接受一个函数或含有映射关系的字典型对象。

in:

data['K'] = data['one'].map({0:'Eric',4:'Rick',8:'Morty'})

print("data:",data)

out:

data:    one  two  three  four   K
     a    0    1      2     3   Eric
     b    4    5      6     7   Rick
     c    8    9     10    11  Morty
     e   12   13     14    15    NaN

排序和排名


根据条件对数据集排序是一种重要的内置运算,可用于处理需要获得排序数据的数据集问题。要对行或列索引进行排序(按字典排序),可使用sort_index的方法,它将返回一个已排序后的新对象,数据默认是按升序排序的,如果需要降序的可以通过在函数中使用ascending =  False,若是Series按值排序的话可以使用order方法。在对值排序的时候也可使用sort_valuesd进行排序,但在多列数据框的情况下需要通过by来选取需要排序的列在排序的时候任何缺失值都会放在末尾。

in:

frame = DataFrame(np.arange(8).reshape((2,4)),index = ['two','one'],columns = ['d','a','c','b'])

print("frame.sort_index():",frame.sort_index())

print("frame.sort_index(axis = 1):",frame.sort_index(axis = 1) )

print("frame.sort_values(by = ['c']):",frame.sort_values(by = ['c']))

out:

frame.sort_index():      d  a  c  b
                    one  4  5  6  7
                    two  0  1  2  3
frame.sort_index(axis = 1):      a  b  c  d
                            two  1  3  2  0
                            one  5  7  6  4
frame.sort_values():      d  a  c  b
                     two  0  1  2  3
                     one  4  5  6  7


汇总和计算描述统计

pandas对象拥有一组常用的数学和统计方法。它们大部分都属于约简和汇总统计,用于从Series中提取单个值(如sum和mean)或从DataFrame的行或列中提取一个Series。跟对应的Numpy的数组方法相比,它们都是基于没有缺失数据的假设而构建的。

in:

df = DataFrame([[1.4,np.nan],[7.5,-4.3],[np.nan,np.nan],[0.73,-0.113]],index = ['a','b','c','d'],columns = ['one','two'])

print("df:",df)

print("df.sum():",df.sum())

print("df.sum(axis =1):",df.sum(axis = 1))

print("df.mean(axis = 1):",df.mean(axis = 1))

out:

df:     one    two
    a  1.40    NaN
    b  7.50 -4.300
    c   NaN    NaN
    d  0.73 -0.113
df.sum(): one    9.630
          two   -4.413
dtype: float64
df.sum(axis =1): a    1.400
                 b    3.200
                 c      NaN
                 d    0.617
dtype: float64
df.mean(axis = 1): a    1.4000
                   b    1.6000
                   c       NaN
                   d    0.3085
dtype: float64

描述和汇总统计
方法说明
count非NA值的数量
describe针对Series或各DataFrame列计算汇总统计
min、max计算最小值和最大值
argmin、argmax计算能够获取的到最小值和最大值的索引位置
idxmin、idxmax计算能够获取到最小值和最大值的索引值
quantile计算样本的分位数(0到1)
sum值的总和
mean值的平均数
median值的算术平均数
mad根据平均值计算平均绝对离差
var样本值的方差
std样本值的标准差
skew样本值的偏度(三阶矩)
kurt样本值的峰度(四阶矩)
cumsum样本值的累计和
cummin、cummax样本值的累计最大值和累计最小值
cumprod样本值的累计积
diff计算一阶差分(对时间序列很有用)
pct_change计算百分数变化

处理缺失数据


缺失数据在大部分数据分析应用中都很常见。且pandas上所有的描述统计都排除了缺失数据。而且使用浮点值NaN表示浮点和非浮点数组中的缺失数据,是一种用于方便检测的标记。

in:

string_data = Series(['a','b',np.nan,'c','d'])

print("string_data.isnull():",string_data.isnull())

data = DataFrame(np.arange(16).reshape(4,4))

data.ix[2,3] = np.nan

print("data.isnull():",data.isnull())

out:

string_data.isnull(): 0    False
                      1    False
                      2     True
                      3    False
                      4    False
dtype: bool
data.isnull():        0      1      2      3
                0  False  False  False  False
                1  False  False  False  False
                2  False  False  False   True
                3  False  False  False  False


NA处理方法
方法说明
dropna根据各标签的值中是否存在缺失数据对轴标签进行过滤,可通过调节阔值来决定缺失值的容忍度
fillna用指定值或插值方法(如ffill或bfill)填充缺失数据
isnull返回一个含有布尔值的对象,这些布尔值表示那些值是缺失值NA,该对象的类型与源类型一样
notnulisnull的否定式

in:

print("data.fillna(0):",data.fillna(0))
print("data.fillna(data.mean()):",data.fillna(data.mean()))
print("data.dropna()",data.dropna())

out:

data.fillna(0):     0   1   2     3
                0   0   1   2   3.0
                1   4   5   6   7.0
                2   8   9  10   0.0
                3  12  13  14  15.0
data.fillna(data.mean()):     0   1   2          3
                          0   0   1   2   3.000000
                          1   4   5   6   7.000000
                          2   8   9  10   8.333333
                          3  12  13  14  15.000000
data.dropna()     0   1   2     3
              0   0   1   2   3.0
              1   4   5   6   7.0
              3  12  13  14  15.0



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值