python之pandas学习笔记

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

二、代码详解

1.基础

pandas最核心的就是Series和DataFrame两个数据结构。

这两种类型的数据结构对比如下:

名称 维度 说明
Series 1维 能存储不同类型的数据
DataFrame 2维 表格结构,带有标签,大小可变,并且可以有多种数据类型

定义Series
np.nan相当于null,是定义空值

s = pd.Series([1,3,6,np.nan,44,1])
print(s)

结果:

0     1.0
1     3.0
2     6.0
3     NaN
4    44.0
5     1.0
dtype: float64

定义DataFrame
pd.date_range()生成日期序列
DataFrame(1,2,3)
第一个参数是data数据
第二个参数是index,索引
第三个参数是columns是表的列名
默认规则是只有数据

pd.Categorical()将内容数字化存储,运行速度更快

dates = pd.date_range('20190607',periods=6)
print(dates)

df = pd.DataFrame(np.random.randn(6,4),index=dates,columns=['a','b','c','d'])
print(df)

df1 = pd.DataFrame(np.arange(12).reshape((3,4)))    # 默认df规则
print(df1)

df2 = pd.DataFrame({'A':1.,
                    'B':pd.Timestamp('20130102'),
                    'C':pd.Series(1,index=list(range(4)),dtype='float32'),
                    'D':np.array([3]*4,dtype='int32'),
                    'E':pd.Categorical(['test','train','test','train']),
                    'F':'foo'
                    })
print(df2)

结果:

DatetimeIndex(['2019-06-07', '2019-06-08', '2019-06-09', '2019-06-10',
               '2019-06-11', '2019-06-12'],
              dtype='datetime64[ns]', freq='D')
                   a         b         c         d
2019-06-07  0.484568 -0.439881 -0.960222 -1.520919
2019-06-08  1.054979  1.705260 -0.369167 -0.323814
2019-06-09  1.735345  0.404412 -0.306179 -0.380139
2019-06-10  2.583616  0.947599  0.700119 -3.001477
2019-06-11 -0.469525 -0.147207 -0.044570 -1.684648
2019-06-12 -0.345939  0.294284 -0.434633  0.006824
   0  1   2   3
0  0  1   2   3
1  4  5   6   7
2  8  9  10  11
     A          B    C  D      E    F
0  1.0 2013-01-02  1.0  3   test  foo
1  1.0 2013-01-02  1.0  3  train  foo
2  1.0 2013-01-02  1.0  3   test  foo
3  1.0 2013-01-02  1.0  3  train  foo

下面介绍一些DataFrame的属性
df2指的是一张DataFrame表

名称 说明
df2.dtypes 输出每一列的字符类型
df2.index 输出序号名
df2.columns 输出列名
df2.values 输出所有的值
df2.describe() 输出dataframe的描述(只输出数字类型)
df2.T 输出df2的转置
df2.sort_index(axis=1,ascending=False) 输出对烈面进行排序,1代表列,false代表逆序
df2.sort_index(axis=0,ascending=False) 输出对行号进行排序 ,0代表行,false代表逆序
df2.sort_values(by=‘E’) 输出根据值进行排序

代码;:

print(df2.dtypes)         # 输出每一列的字符类型
print(df2.index)            # 输出序号名
print(df2.columns)          # 输出列名
print(df2.values)           # 输出所有的值
print(df2.describe())       # 输出dataframe的描述
print(df2.T)                # 输出df2的转置
print(df2.sort_index(axis=1,ascending=False))   #输出对列名进行排序
print(df2.sort_index(axis=0,ascending=False))   # 输出对行号进行排序
print(df2.sort_values(by='E'))                  # 输出根据值进行排序

输出结果:

A           float64
B    datetime64[ns]
C           float32
D             int32
E          category
F            object
dtype: object

Int64Index([0, 1, 2, 3], dtype='int64')

Index(['A', 'B', 'C', 'D', 'E', 'F'], dtype='object')

[[1.0 Timestamp('2013-01-02 00:00:00') 1.0 3 'test' 'foo']
 [1.0 Timestamp('2013-01-02 00:00:00') 1.0 3 'train' 'foo']
 [1.0 Timestamp('2013-01-02 00:00:00') 1.0 3 'test' 'foo']
 [1.0 Timestamp('2013-01-02 00:00:00') 1.0 3 'train' 'foo']]
 
         A    C    D
count  4.0  4.0  4.0
mean   1.0  1.0  3.0
std    0.0  0.0  0.0
min    1.0  1.0  3.0
25%    1.0  1.0  3.0
50%    1.0  1.0  3.0
75%    1.0  1.0  3.0
max    1.0  1.0  3.0

                     0         ...                             3
A                    1         ...                             1
B  2013-01-02 00:00:00         ...           2013-01-02 00:00:00
C                    1         ...                             1
D                    3         ...                             3
E                 test         ...                         train
F                  foo         ...                           foo

[6 rows x 4 columns]

     F      E  D    C          B    A
0  foo   test  3  1.0 2013-01-02  1.0
1  foo  train  3  1.0 2013-01-02  1.0
2  foo   test  3  1.0 2013-01-02  1.0
3  foo  train  3  1.0 2013-01-02  1.0

     A          B    C  D      E    F
3  1.0 2013-01-02  1.0  3  train  foo
2  1.0 2013-01-02  1.0  3   test  foo
1  1.0 2013-01-02  1.0  3  train  foo
0  1.0 2013-01-02  1.0  3   test  foo

     A          B    C  D      E    F
0  1.0 2013-01-02  1.0  3   test  foo
2  1.0 2013-01-02  1.0  3   test  foo
1  1.0 2013-01-02  1.0  3  train  foo
3  1.0 2013-01-02  1.0  3  train  foo

2.选择数据

第一种方式:
普通的索引
df[‘A’]=df.A这两种都是筛选列为A的
df[0:3],df[‘20190608’:‘20190610’] 这两种都是筛选行为0:3的值,后面那种是行的序号的名字。
代码;

dates = pd.date_range('20190607',periods=6)
df = pd.DataFrame(np.arange(24).reshape((6,4)),index=dates,columns=['A','B','C','D'])
print(df)
print(df['A'],df.A)                # 筛选列为A的
print(df[0:3],df['20190608':'20190610'])   # 筛选行为0:3的值

结果;

 A   B   C   D
2019-06-07   0   1   2   3
2019-06-08   4   5   6   7
2019-06-09   8   9  10  11
2019-06-10  12  13  14  15
2019-06-11  16  17  18  19
2019-06-12  20  21  22  23

2019-06-07     0
2019-06-08     4
2019-06-09     8
2019-06-10    12
2019-06-11    16
2019-06-12    20
Freq: D, Name: A, dtype: int32 

2019-06-07     0
2019-06-08     4
2019-06-09     8
2019-06-10    12
2019-06-11    16
2019-06-12    20
Freq: D, Name: A, dtype: int32

            A  B   C   D
2019-06-07  0  1   2   3
2019-06-08  4  5   6   7
2019-06-09  8  9  10  11       
      
 A   B   C   D
2019-06-08   4   5   6   7
2019-06-09   8   9  10  11
2019-06-10  12  13  14  15

第二种方式是标签索引
select by label :loc方法
通过代码看loc使用方法,下列df都是上述的df
代码;

print(df.loc['20190608'])       # 筛选20190608这一行的数据
print(df.loc[:,['A','B']])      # 筛选A,B这两列的数据
print(df.loc['20190607',['A','B']])  # 筛选20190607这一行  和A,B这两列的数据

结果:

A    4
B    5
C    6
D    7
Name: 2019-06-08 00:00:00, dtype: int32

             A   B
2019-06-07   0   1
2019-06-08   4   5
2019-06-09   8   9
2019-06-10  12  13
2019-06-11  16  17
2019-06-12  20  21

A    0
B    1
Name: 2019-06-07 00:00:00, dtype: int32

第三种通过行列号索引
select by position:iloc
iloc[]索引只能是行列号,不能像loc一样用标签
代码展示;

# select by position :iloc       #通过行号列号索引
print(df.iloc[3:5,1:3])          # 切片3:5行  1:3列
print(df.iloc[[1,3,5],1:3])      # 切片 1,3,5行,1:3列

结果:

 B   C
2019-06-10  13  14
2019-06-11  17  18

             B   C
2019-06-08   5   6
2019-06-10  13  14
2019-06-12  21  22

第四种方式 ix
mixed selection:ix
ix方法可以标签与行列号混用
代码:

# mixed selection:ix
print(df.ix[:3,['A','C']])       # 筛选前三行和A,C列数据

结果:

            A   C
2019-06-07  0   2
2019-06-08  4   6
2019-06-09  8  10

第五种索引
df.A>8 :满足A列中大于8的所有行
代码;

# Boolean indexing
print(df[df.A>8])   # 满足df.A大于8的所有行

结果:

             A   B   C   D
2019-06-10  12  13  14  15
2019-06-11  16  17  18  19
2019-06-12  20  21  22  23

第三讲、设置值

通过不同的方法改变dataframe中的值
可以通过上述方式赋值
loc
iloc
df[df.A>4]
df[‘F’]
df[]里面单个内容时代表是列,如果是0:3,则代表是0到3行

代码:

import numpy as np
import pandas as pd

dates = pd.date_range('20190607',periods=6)
df = pd.DataFrame(np.arange(24).reshape((6,4)),index=dates,columns=['A','B','C','D'])
print(df)
df.iloc[2,2] =1111                 # 更改数值
df.loc['20190610','B']=2222              # 更改数值
#df[df.A>4] = 0                     # 当A列中的中大于4的项全部变成0,包括B列
#df.A[df.A>4] = 0                  #仅仅A列中大于4的项变成0
df.B[df.A>4] = 0                  #确认A列中大于4的项使得B列中与之对应的项变成零
df['F'] = np.nan
df['E'] = pd.Series([1,2,3,4,5,6],index=pd.date_range('20190607',periods=6))
print(df)

结果;

             A   B   C   D
2019-06-07   0   1   2   3
2019-06-08   4   5   6   7
2019-06-09   8   9  10  11
2019-06-10  12  13  14  15
2019-06-11  16  17  18  19
2019-06-12  20  21  22  23


             A  B     C   D   F  E
2019-06-07   0  1     2   3 NaN  1
2019-06-08   4  5     6   7 NaN  2
2019-06-09   8  0  1111  11 NaN  3
2019-06-10  12  0    14  15 NaN  4
2019-06-11  16  0    18  19 NaN  5
2019-06-12  20  0    22  23 NaN  6

第四讲、处理丢失数据

属性 说明
df.dropna(axis=1,how=‘any’) 丢弃缺失方法,how={‘any’,‘all’} how代表的是丢掉方式, any是指只要存在1个或者1个以上,该列就要丢弃,all是必须此列全丢失nan值才能丢弃。
df.fillna(value=0) 将nan值填充成value值
df.isnull() isunull判断是否有nan值,若有,即在那个位置返回true
np.any(df.isnull())==True 判断是否至少有一个nan值,若有则返回True

代码:

import numpy as np
import pandas as pd

dates = pd.date_range('20190607',periods=6)
df = pd.DataFrame(np.arange(24).reshape((6,4)),index=dates,columns=['A','B','C','D'])

df.iloc[0,1] = np.nan
df.iloc[1,2] = np.nan
print(df)
print(df.dropna(axis=1,how='any'))   # how ={'any','all'}  how 代表的是丢掉方式
print(df.fillna(value=0))              # 将nan值填充成value值
print(df.isnull())                     # isnull判断是否有nan值,若有,即在那个位置返回true

print(np.any(df.isnull())==True)        # 判断是否至少有一个nan值,若有则返回True

结果;

             A     B     C   D
2019-06-07   0   NaN   2.0   3
2019-06-08   4   5.0   NaN   7
2019-06-09   8   9.0  10.0  11
2019-06-10  12  13.0  14.0  15
2019-06-11  16  17.0  18.0  19
2019-06-12  20  21.0  22.0  23

             A   D
2019-06-07   0   3
2019-06-08   4   7
2019-06-09   8  11
2019-06-10  12  15
2019-06-11  16  19
2019-06-12  20  23

             A     B     C   D
2019-06-07   0   0.0   2.0   3
2019-06-08   4   5.0   0.0   7
2019-06-09   8   9.0  10.0  11
2019-06-10  12  13.0  14.0  15
2019-06-11  16  17.0  18.0  19
2019-06-12  20  21.0  22.0  23

                A      B      C      D
2019-06-07  False   True  False  False
2019-06-08  False  False   True  False
2019-06-09  False  False  False  False
2019-06-10  False  False  False  False
2019-06-11  False  False  False  False
2019-06-12  False  False  False  False

True

第五讲、导入导出

导入导出方法很多,但是格式很相似,无非就是打开格式和保存格式不同。
可以查看官方文档,这里只简单看一下用法。
代码;

import pandas as pd

data = pd.read_csv('student.csv')   # 读取文件
print(data)
print(type(data))

data.to_pickle('student.pickle')    # 保存文件

代码可以读出student.csv的数据
data的类型是pandas.core.frame.DataFrame
保存形式为pickle形式,序列化

第六讲、合并concat

先简单运用concat合并dataframe
pd.concat([df1,df2,df3],axis=0) # 竖向合并
当axis为1时,为横向合并。
pd.concat([df1,df2,df3],axis=0,ignore_index=True) # 竖向合并,忽略index
ignore_index为真忽略每个dataframe中的index,重新排列
代码;

# concatenating
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)         # 竖向合并
print(res)

res = pd.concat([df1,df2,df3],axis=0,ignore_index=True)         # 竖向合并,忽略index
print(res)

下面看concat的另一个参数join{‘inner’,‘outer’}
对于一些表中列名并完全相同的时候合并要用到join,outer是默认加入方式,将合并的几个表格的列全部列出来,没有值的设为nan值。inner是取几个表列的交集。
注意:python3后默认加入方式要加一个参数sort=True
下面通过代码展示:

df1 = pd.DataFrame(np.ones((3,4))*0,columns=['a','b','c','d'],index=[1,2,3])
df2 = pd.DataFrame(np.ones((3,4))*1,columns=['b','c','d','e'],index=[2,3,4])


res = pd.concat([df1,df2],join='outer',sort = True)   # 默认加入方式
print(res)

res = pd.concat([df1,df2],join='inner',ignore_index=True)    # inner模式
print(res)

结果;

a    b    c    d    e
1  0.0  0.0  0.0  0.0  NaN
2  0.0  0.0  0.0  0.0  NaN
3  0.0  0.0  0.0  0.0  NaN
2  NaN  1.0  1.0  1.0  1.0
3  NaN  1.0  1.0  1.0  1.0
4  NaN  1.0  1.0  1.0  1.0

     b    c    d
0  0.0  0.0  0.0
1  0.0  0.0  0.0
2  0.0  0.0  0.0
3  1.0  1.0  1.0
4  1.0  1.0  1.0
5  1.0  1.0  1.0

另一个参数join_axes
join_axes=[df1.index]使用df1表格的索引
代码:

# join_axes
df1 = pd.DataFrame(np.ones((3,4))*0,columns=['a','b','c','d'],index=[1,2,3])
df2 = pd.DataFrame(np.ones((3,4))*1,columns=['b','c','d','e'],index=[2,3,4])
res = pd.concat([df1,df2],axis=1,join_axes=[df1.index])       # 横向合并,按照df1的index合并
print(res)

结果;

     a    b    c    d    b    c    d    e
1  0.0  0.0  0.0  0.0  NaN  NaN  NaN  NaN
2  0.0  0.0  0.0  0.0  1.0  1.0  1.0  1.0
3  0.0  0.0  0.0  0.0  1.0  1.0  1.0  1.0

append()方法
指定一个df调用此方法,然后扩展此表
可以添加df和序列
代码;

# append
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))*1,columns=['a','b','c','d'])
res=df1.append([df2,df3],ignore_index=True)          # 竖向添加
print(res)
s1 = pd.Series([1,2,3,4],index=['a','b','c','d'])
res = df1.append(s1,ignore_index=True)    # 添加一个序列
print(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  1.0  1.0  1.0  1.0
7  1.0  1.0  1.0  1.0
8  1.0  1.0  1.0  1.0

     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  2.0  3.0  4.0

第七讲、合并merge

利用关键字进行合并,有点像数据库中的主键。
上来举一个简单的例子。
代码;

import pandas as pd
# merging two df by key/keys.(may be used in database)
# simple example
left = pd.DataFrame({'key':['K0','K1','K2','K3'],
                     'A':['A0','A1','A2','A3'],
                     'B':['B0','B1','B2','B3']})
right = pd.DataFrame({'key':['K0','K1','K2','K3'],
                     'C':['C0','C1','C2','C3'],
                      'D':['D0','D1','D2','D3']})

print(left)
print(right)
res = pd.merge(left,right,on='key')
print(res)

结果:

    A   B key
0  A0  B0  K0
1  A1  B1  K1
2  A2  B2  K2
3  A3  B3  K3

    C   D key
0  C0  D0  K0
1  C1  D1  K1
2  C2  D2  K2
3  C3  D3  K3

    A   B key   C   D
0  A0  B0  K0  C0  D0
1  A1  B1  K1  C1  D1
2  A2  B2  K2  C2  D2
3  A3  B3  K3  C3  D3

可以看出,是根据key这一列的值进行了合并。

下面看由两个key控制的例子
merge()里面也有一个how的参数
how = [‘left’,‘right’,‘outer’,‘inner’]
‘left’指的是关键字的内容按照第一个dataframe来
‘right’指的是关键字的内容按照最后一个dataframe来
‘outer’指的是关键字

# consider two keys
left = pd.DataFrame({'key1':['K0','K0','K1','K2'],
                     'key2':['K0','K1','K0','K1'],
                     'A':['A0','A1','A2','A3'],
                     'B':['B0','B1','B2','B3']})
right = pd.DataFrame({'key1':['K0','K1','K1','K2'],
                     'key2':['K0','K0','K0','K0'],
                     'C':['C0','C1','C2','C3'],
                      'D':['D0','D1','D2','D3']})

print(left)
print(right)
how = ['left','right','outer','inner']
res = pd.merge(left,right,on=['key1','key2'],how='inner')
print(res)

结果:

    A   B key1 key2
0  A0  B0   K0   K0
1  A1  B1   K0   K1
2  A2  B2   K1   K0
3  A3  B3   K2   K1

    C   D key1 key2
0  C0  D0   K0   K0
1  C1  D1   K1   K0
2  C2  D2   K1   K0
3  C3  D3   K2   K0

    A   B key1 key2   C   D
0  A0  B0   K0   K0  C0  D0
1  A2  B2   K1   K0  C1  D1
2  A2  B2   K1   K0  C2  D2

下一个参数indicator参数
当indicator= True时,会给出一列用来存储两个df中值的存在情况
当indicator=‘ indicator_column’ 会重命名该列
代码;

# indicator
df1 = pd.DataFrame({'col1':[0,1],'col_left':['a','b']})
df2 = pd.DataFrame({'col1':[1,2,2],'col_right':[2,2,2]})
print(df1)
print(df2)
#res = pd.merge(df1,df2,on='col1',how='outer',indicator=True)   # 给出一列用来存储两个df中值的存在情况
# give the indicator a custom name
res = pd.merge(df1,df2,on='col1',how='outer',indicator='indicator_column')
print(res)

结果:

   col1 col_left
0     0        a
1     1        b

   col1  col_right
0     1          2
1     2          2
2     2          2

   col1 col_left  col_right indicator_column
0     0        a        NaN        left_only
1     1        b        2.0             both
2     2      NaN        2.0       right_only
3     2      NaN        2.0       right_only

merge 用 索引
pd.merge(left,right,left_index=True,right_index=True,how=‘outer’)
令left_index和right_index都为True
同时how的作用同前面的一样
代码:

# merged by index

left = pd.DataFrame({'A':['A0','A1','A2'],
                     'B':['B0','B1','B2']},
                    index=['K0','K1','K2'])
right = pd.DataFrame({ 'C':['C0','C1','C2'],
                      'D':['D0','D1','D2']},
                     index=['K0','K2','K3'])
print(left)
print(right)

# left_index and right_index
res = pd.merge(left,right,left_index=True,right_index=True,how='outer')   # 基于index合并
# res = pd.merge(left,right,left_index=True,right_index=True,how='inner')
print(res)
print('*'*50)

结果;

     A   B
K0  A0  B0
K1  A1  B1
K2  A2  B2

     C   D
K0  C0  D0
K2  C1  D1
K3  C2  D2

      A    B    C    D
K0   A0   B0   C0   D0
K1   A1   B1  NaN  NaN
K2   A2   B2   C1   D1
K3  NaN  NaN   C2   D2

当一个表中关键字有相同的时候,要全部对应起来
pd.merge(boys,girls,on=‘k’,suffixes=[’_boy’,’_girl’],how=‘outer’)
suffixes参数是在要合并的两个表中列名后面加的内容。
代码:

# handle overlapping
boys = pd.DataFrame({'k':['K0','K1','K2'],'age':[1,2,3]})
girls = pd.DataFrame({'k':['K0','K0','K3'],'age':[4,5,6]})

print(boys)
print(girls)
res = pd.merge(boys,girls,on='k',suffixes=['_boy','_girl'],how='outer')
print(res)

结果:

   age   k
0    1  K0
1    2  K1
2    3  K2

   age   k
0    4  K0
1    5  K0
2    6  K3

   age_boy   k  age_girl
0      1.0  K0       4.0
1      1.0  K0       5.0
2      2.0  K1       NaN
3      3.0  K2       NaN
4      NaN  K3       6.0

第八讲、plot画图

plot在matplotlib经常使用,在pandas中也可以使用。
plot method:
‘bar’,‘hist’,‘box’,‘kde’,‘area’,‘scatter’,‘hexbin’,‘pie’
plot有很多图,大家需要的可以找官方文档学习一下。这里展示一下plot使用。
我们随机了一组数据,进行画图操作。
代码;

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# plot data

# Series  线性数据
data = pd.Series(np.random.randn(1000),index=np.arange(1000))
data = data.cumsum()

# DataFrame
data = pd.DataFrame(np.random.randn(1000,4),
                    index=np.arange(1000),
                    columns=list("ABCD"))
print(data.head())
data=data.cumsum()  # 累加函数

data.plot()
# plot method:
# 'bar','hist','box','kde','area','scatter','hexbin','pie'
 ax=data.plot.scatter(x='A',y='B',color='DarkBlue',label='Class 1')
 data.plot.scatter(x='A',y='C',color='DarkGreen',label='Class 2',ax=ax)
plt.show()

结果;
线性图
散点图

(未完待续)

猜你喜欢

转载自blog.csdn.net/Prince_IT/article/details/92402790