pandas模块基础学习

Pandas类似R语言中的数据框(DataFrame),Pandas基于Numpy,但是对于数据框结构的处理比Numpy要来的容易。

1. Pandas的基本数据结构和使用

Pandas有两个主要的数据结构:Series和DataFrame。Series类似Numpy中的一维数组,DataFrame则是使用较多的多维表格数据结构。

  • Series的创建
>>>import numpy as np
>>>import pandas as pd
>>>s=pd.Series([1,2,3,np.nan,44,1])  # np.nan创建一个缺失数值
>>>s # 若未指定,Series会自动建立index,此处自动建立索引0-5
0     1.0
1     2.0
2     3.0
3     NaN
4    44.0
5     1.0
dtype: float64
  • DataFrame的创建
>>>dates=pd.date_range('20170101',periods=6)
>>>dates
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
               '2017-01-05', '2017-01-06'],
              dtype='datetime64[ns]', freq='D')
>>>df=pd.DataFrame(np.random.randn(6,4),index=dates,columns=['a','b','c','d'])
>>>df
                     a         b         c         d
2017-01-01 -1.993447  1.272175 -1.578337 -1.972526
2017-01-02  0.092701 -0.503654 -0.540655 -0.126386
2017-01-03  0.191769 -0.578872 -1.693449  0.457891
2017-01-04  2.121120  0.521884 -0.419368 -1.916585
2017-01-05  1.642063  0.222134  0.108531 -1.858906
2017-01-06  0.636639  0.487491  0.617841 -1.597920

DataFrame可以跟Numpy一样根据索引取出其中的数据,只是DataFrame索引方式更加多样化。DataFrame不仅可以根据默认的行列编号来索引,还可以根据标签序列来索引。
还可以采用字典的方式创建DataFrame:

>>>df2=pd.DataFrame({'a':1,'b':'hello kitty','c':np.arange(2),'d':['o','k']})
>>>df2
     a            b  c  d
0  1  hello kitty  0  o
1  1  hello kitty  1  k
  • 对于DataFrame的一些属性也可以采用相应的方法查看
dtype  # 查看数据类型
index  # 查看行序列或者索引
columns  # 查看各列的标签
values # 查看数据框内的数据,也即不含表头索引的数据
describe # 查看数据的一些信息,如每一列的极值,均值,中位数之类的,只能对数值型数据统计信息
transpose # 转置,也可用T来操作
sort_index  # 排序,可按行或列index排序输出
sort_values  # 按数据值来排序

一些例子

>>>df2.dtypes
a     int64
b    object
c     int64
d    object
dtype: object
>>>df2.index
RangeIndex(start=0, stop=2, step=1)
>>>df2.columns
Index(['a', 'b', 'c', 'd'], dtype='object')
>>>df2.values
array([[1, 'hello kitty', 0, 'o'],
       [1, 'hello kitty', 1, 'k']], dtype=object)
>>>df2.describe # 只能对数值型数据统计信息
         a         c
count  2.0  2.000000
mean   1.0  0.500000
std    0.0  0.707107
min    1.0  0.000000
25%    1.0  0.250000
50%    1.0  0.500000
75%    1.0  0.750000
max    1.0  1.000000
>>>df2.T
             0            1
a            1            1
b  hello kitty  hello kitty
c            0            1
d            o            k
>>>df2.sort_index(axis=1,ascending=False) # axis=1 按列标签从大到小排列
     d  c            b  a
0  o  0  hello kitty  1
1  k  1  hello kitty  1
>>>df2.sort_index(axis=0,ascending=False)  # 按行标签从大到小排序
     a            b  c  d
1  1  hello kitty  1  k
0  1  hello kitty  0  o
>>>df2.sort_values(by="c",ascending=False) # 按c列的值从大到小排序
    a            b  c  d
1  1  hello kitty  1  k
0  1  hello kitty  0  o

2. 从DataFrame中筛选取出目的数据

从DataFrame中取出目的数据方法有多种,一般常用的有:
 - 直接根据索引选取
 - 根据标签选取(纵向选择列):loc
 - 根据序列(横向选择行): iloc
 - 组合使用标签序列来选取特定位置的数据: ix
 - 通过逻辑判断筛选

  • 简单选取
>>>import numpy as np
>>>import pandas as pd
>>>dates=pd.date_range('20170101',periods=6)
>>>df=pd.DataFrame(np.arange(24).reshape((6,4)),index=dates,columns=['a','b','c','d'])
>>>df
               a   b   c   d
2017-01-01   0   1   2   3
2017-01-02   4   5   6   7
2017-01-03   8   9  10  11
2017-01-04  12  13  14  15
2017-01-05  16  17  18  19
2017-01-06  20  21  22  23
>>>df['a']         # 根据表签直接选取a列,也可用df.a,结果相同
2017-01-01     0
2017-01-02     4
2017-01-03     8
2017-01-04    12
2017-01-05    16
2017-01-06    20
Freq: D, Name: a, dtype: int64
>>>df[0:3]    # 选择前3行,也可用行标签 df['2017-01-01':'2017-01-03'],结果相同,但是无法用此法选择多列
              a  b   c   d
2017-01-01  0  1   2   3
2017-01-02  4  5   6   7
2017-01-03  8  9  10  11
  • loc使用显式的行标签来选取数据
    DataFrame行的表示方式有两种,一种是通过显式的行标签来索引,另一种是通过默认隐式的行号来索引。loc方法是通过行标签来索引选取目标行,可以配合列标签来选取特定位置的数据。
>>>df.loc['2017-01-01':'2017-01-03']
              a  b   c   d
2017-01-01  0  1   2   3
2017-01-02  4  5   6   7
2017-01-03  8  9  10  11
>>>df.loc['2017-01-01',['a','b']]   # 选取特定行的a,b列
a    0
b    1
Name: 2017-01-01 00:00:00, dtype: int64
  • iloc使用隐式的行序列号来选取数据
    使用iloc可以搭配列序列号来更简单的选取特定位点的数据
>>>df.iloc[3,1]
13
>>>df.iloc[1:3,2:4]
               c   d
2017-01-02   6   7
2017-01-03  10  11
  • ix利用ix可以混用显式标签与隐式序列号
    loc只能使用显式标签来选取数据,而iloc只能使用隐式序列号来选取数据,ix则能将二者结合起来使用。
>>> df.ix[3:5,['a','b']]
              a   b
2017-01-04  12  13
2017-01-05  16  17
  • 使用逻辑判断来选取数据
>>>df
               a   b   c   d
2017-01-01   0   1   2   3
2017-01-02   4   5   6   7
2017-01-03   8   9  10  11
2017-01-04  12  13  14  15
2017-01-05  16  17  18  19
2017-01-06  20  21  22  23
>>>df[df['a']>5]  # 等价于df[df.a>5]
               a   b   c   d
2017-01-03   8   9  10  11
2017-01-04  12  13  14  15
2017-01-05  16  17  18  19
2017-01-06  20  21  22  23

3. Pandas设置特定位置值

>>>import numpy as np
>>>import pandas as pd
>>>dates=pd.date_range('20170101',periods=6)
>>>datas=np.arange(24).reshape((6,4))
>>>columns=['a','b','c','d']
>>>df=pd.DataFra  me(data=datas,index=dates,colums=columns)
>>>df.iloc[2,2:4]=111  # 将第2行2,3列位置的数据改为111
               a   b    c    d
2017-01-01   0   1    2    3
2017-01-02   4   5    6    7
2017-01-03   8   9  111  111
2017-01-04  12  13   14   15
2017-01-05  16  17   18   19
2017-01-06  20  21   22   23
>>>df.b[df['a']>10]=0  # 等价于df.b[df.a>10] # 以a列大于10的数的位置为参考,改变b列相应行的数值为0
               a  b    c    d
2017-01-01   0  1    2    3
2017-01-02   4  5    6    7
2017-01-03   8  9  111  111
2017-01-04  12  0   14   15
2017-01-05  16  0   18   19
2017-01-06  20  0   22   23
>>>df['f']=np.nan   # 新建f列并设置数值为np.nan
             a  b    c    d   f
2017-01-01   0  1    2    3 NaN
2017-01-02   4  5    6    7 NaN
2017-01-03   8  9  111  111 NaN
2017-01-04  12  0   14   15 NaN
2017-01-05  16  0   18   19 NaN
2017-01-06  20  0   22   23 NaN
>>>
# 用上面的方法也可以加上`Series`序列,但是必须与列长度一致
>>>df['e']=pd.Series(np.arange(6),index=dates)
>>>df
             a  b    c    d   f  e
2017-01-01   0  1    2    3 NaN  0
2017-01-02   4  5    6    7 NaN  1
2017-01-03   8  9  111  111 NaN  2
2017-01-04  12  0   14   15 NaN  3
2017-01-05  16  0   18   19 NaN  4
2017-01-06  20  0   22   23 NaN  5

4. 处理丢失数据

有时候我们的数据中会有一些空的或者缺失(NaN)数据,使用dropna可以选择性的删除或填补这些NaN数据。drop函数可以选择性的删除行或者列,drop_duplicates去除冗余。fillna则将NaN值用其他值替换。操作后不改变原值,若要保存更改需重新赋值。

>>>import numpy as np
>>>import pandas as pd
>>>df=pd.DataFrame(np.arange(24).reshape(6,4),index=pd.date_range('20170101',periods=6),columns=['a','b','c','d'])
>>>df
              a   b   c   d
2017-01-01   0   1   2   3
2017-01-02   4   5   6   7
2017-01-03   8   9  10  11
2017-01-04  12  13  14  15
2017-01-05  16  17  18  19
2017-01-06  20  21  22  23
>>>df.iloc[1,3]=np.nan
>>>di.iloc[3,2]=np.nan
>>>df.
             a   b     c     d
2017-01-01   0   1   2.0   3.0
2017-01-02   4   5   6.0   NaN
2017-01-03   8   9  10.0  11.0
2017-01-04  12  13   NaN  15.0
2017-01-05  16  17  18.0  19.0
2017-01-06  20  21  22.0  23.0
>>>df.dropna(axis=0,how='any')  # axis=0(1)表示将含有NaN的行(列)删除。
      # how='any'表示只要行(或列,视axis取值而定)含有NaN则将该行(列)删除,
      # how='all'表示当某行(列)全部为NaN时才删除
             a   b     c     d
2017-01-01   0   1   2.0   3.0
2017-01-03   8   9  10.0  11.0
2017-01-05  16  17  18.0  19.0
2017-01-06  20  21  22.0  23.0
>>>df.fillna(value=55)
             a   b     c     d
2017-01-01   0   1   2.0   3.0
2017-01-02   4   5   6.0  55.0
2017-01-03   8   9  10.0  11.0
2017-01-04  12  13  55.0  15.0
2017-01-05  16  17  18.0  19.0
2017-01-06  20  21  22.0  23.0

还可以利用函数来检查数据中是否有或者全部为NaN

>>>np.any(df.isnull())==True
True
>>>np.all(df.isnull())==True
False

5. 数据的导入以及导出

一般excel文件以csv方式读入,pd.read_csv(file),data保存为filedata.to_csv(file)

6. 数据添加合并

本节主要学习Pandas的一些简单基本的数据添加合并方法:concat,append

  • concat合并方式类似于Numpy的concatenate方法,可横向或者竖向合并。
>>>import numpy as np
>>>import pandas as pd
>>> df1=pd.DataFrame(np.ones((3,4))*0,columns=['a','b','c','d'])
>>> df2=pd.DataFrame(np.ones((3,4))*1,columns=['a','b','c','d'])
>>> df3=pd.DataFrame(np.ones((3,4))*2,columns=['a','b','c','d'])
>>>res=pd.concat([df1,df2,df3],axis=0)  
# axis=0表示按行堆叠合并,axis=1表示按列左右合并
>>>res
       a    b    c    d
0  0.0  0.0  0.0  0.0
1  0.0  0.0  0.0  0.0
2  0.0  0.0  0.0  0.0
0  1.0  1.0  1.0  1.0
1  1.0  1.0  1.0  1.0
2  1.0  1.0  1.0  1.0
0  2.0  2.0  2.0  2.0
1  2.0  2.0  2.0  2.0
2  2.0  2.0  2.0  2.0
>>>
# 使用ignore_index=True参数可以重置行标签
>>>res=pd.concat([df1,df2,df3],axis=0,ignore_index=True)
>>>res
       a    b    c    d
0  0.0  0.0  0.0  0.0
1  0.0  0.0  0.0  0.0
2  0.0  0.0  0.0  0.0
3  1.0  1.0  1.0  1.0
4  1.0  1.0  1.0  1.0
5  1.0  1.0  1.0  1.0
6  2.0  2.0  2.0  2.0
7  2.0  2.0  2.0  2.0
8  2.0  2.0  2.0  2.0

join参数提供了更多样化的合并方式。join=outer为默认值,表示将几个合并的数据都用上,具有相同列标签的合二为一,上下合并,不同列标签的独自成列,原来没有数值的位置以NaN填充;join=inner则只将具有相同列标签的(行)列上下合并,其余的列舍弃。简言之,outer代表并集,inner代表交集**。

>>>import numpy as np
>>>import pandas as pd
>>>df1=pd.DataFrame(np.ones((3,4)),index=[1,2,3],columns=['a','b','c','d'])
>>>df2=pd.DataFrame(np.ones((3,4))*2,index=[1,2,3],columns=['b','c','d','e'])
>>>res=pd.concat([df1,df2],axis=0,join='outer')
>>>res
       a    b    c    d    e
1  1.0  1.0  1.0  1.0  NaN
2  1.0  1.0  1.0  1.0  NaN
3  1.0  1.0  1.0  1.0  NaN
1  NaN  2.0  2.0  2.0  2.0
2  NaN  2.0  2.0  2.0  2.0
3  NaN  2.0  2.0  2.0  2.0
>>>res1=pd.concat([df1,df2],axis=1,join='outer') 
 # axis=1表示按列左右合并具有相同的行标签的,其余的各成一行,NaN补齐空缺
>>>res1
       a    b    c    d    b    c    d    e
1  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
2  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
3  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
>>>res2=pd.concat([df1,df2],axis=0,join='inner',ignore_index=True) 
# 将具有相同列标签的列上下合并
>>>res2
     b    c    d
0  1.0  1.0  1.0
1  1.0  1.0  1.0
2  1.0  1.0  1.0
3  2.0  2.0  2.0
4  2.0  2.0  2.0
5  2.0  2.0  2.0

join_axes参数可以设定参考系,以设定的参考来合并,参考系中没有的舍弃掉

>>>import numpy as np
>>>import pandas as pd
>>>df1=pd.DataFrame(np.ones((3,4)),index=[1,2,3],columns=['a','b','c','d'])
>>> df2=pd.DataFrame(np.ones((3,4))*2,index=[2,3,4],columns=['b','c','d','e'])
>>>res3=pd.concat([df1,df2],axis=0,join_axes=[df1.columns])
# 以df1的列标签为参考上下合并拥有相同列标签的列
>>>res3
       a    b    c    d
1  1.0  1.0  1.0  1.0
2  1.0  1.0  1.0  1.0
3  1.0  1.0  1.0  1.0
2  NaN  2.0  2.0  2.0
3  NaN  2.0  2.0  2.0
4  NaN  2.0  2.0  2.0
>>>res4=pd.concat([df1,df2],axis=1,join_axes=[df1.index])
# 以df1行标签为参考,左右合并拥有相同行标签的各列
       a    b    c    d    b    c    d    e
1  1.0  1.0  1.0  1.0  NaN  NaN  NaN  NaN
2  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
3  1.0  1.0  1.0  1.0  2.0  2.0  2.0  2.0
  • append只有上下合并,没有左右合并
>>>df1=pd.DataFrame(np.ones((3,4)),index=[1,2,3],columns=['a','b','c','d'])
>>> df2=pd.DataFrame(np.ones((3,4))*2,index=[2,3,4],columns=['b','c','d','e'])
>>>res5=df1.append(df2,ignore_index=True)
>>>res5
       a    b    c    d    e
0  1.0  1.0  1.0  1.0  NaN
1  1.0  1.0  1.0  1.0  NaN
2  1.0  1.0  1.0  1.0  NaN
3  NaN  2.0  2.0  2.0  2.0
4  NaN  2.0  2.0  2.0  2.0
5  NaN  2.0  2.0  2.0  2.0

7. Pandas高级合并:merge

merge合并与concat类似,只是merge可以通过一个或多个键将两个数据集的行连接起来。

merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, 
                                             sort=False, suffixes=('_x', '_y'), copy=True, indicator=False)

# 参数说明:
left与right:两个不同的DataFrame
how:指的是合并(连接)的方式有inner(内连接),left(左外连接),right(右外连接),outer(全外连接);默认为inner
on : 指的是用于连接的列索引名称。必须存在右右两个DataFrame对象中,如果没有指定且其他参数也未指定则以两个DataFrame的列名交集做为连接键
left_on:左侧DataFrame中用作连接键的列名;这个参数中左右列名不相同,但代表的含义相同时非常有用。
right_on:右侧DataFrame中用作 连接键的列名
left_index:使用左侧DataFrame中的行索引做为连接键
right_index:使用右侧DataFrame中的行索引做为连接键
sort:默认为True,将合并的数据进行排序。在大多数情况下设置为False可以提高性能
suffixes:字符串值组成的元组,用于指定当左右DataFrame存在相同列名时在列名后面附加的后缀名称,默认为('_x','_y')
copy:默认为True,总是将数据复制到数据结构中;大多数情况下设置为False可以提高性能
indicator:显示合并数据中来源情况;如只来自己于左边(left_only)、两者(both)
>>>import pandas as pd
>>>df1=pd.DataFrame({'key':['k0','k1','k2','k3'],'A':['a0','a1','a2','a3'],'B':['b0','b1','b2','b3']})
>>>df2=pd.DataFrame({'key':['k0','k1','k2','k3'],'C':['c0','c1','c2','c3'],'D':['d0','d1','d2','d3']})
>>> res=pd.merge(df1,df2,on='key',indicator=True)
>>>res
    A   B key   C   D _merge
0  a0  b0  k0  c0  d0   both
1  a1  b1  k1  c1  d1   both
2  a2  b2  k2  c2  d2   both
3  a3  b3  k3  c3  d3   both

依据行index合并与依据列key合并用法类似

>>>res2=pd.merge(df1,df2,left_index=True,right_index=True,indicator=True)
>>>res2
    A   B key_x   C   D key_y _merge
0  a0  b0    k0  c0  d0    k0   both
1  a1  b1    k1  c1  d1    k1   both
2  a2  b2    k2  c2  d2    k2   both
3  a3  b3    k3  c3  d3    k3   both
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容