python-pandas-Series和DataFrame的基本功能

时间:2021-07-28 02:22:40

内容简介

pandas是一个强大的工具,他有两种主要的数据结构:Series和DataFrame,还有一些基于这两种结构的基本功能,以及汇总和统计功能,接下来会分4篇博客来详细的介绍pandas的使用。这4篇博客的主题为:

1)Series和DataFrame介绍和构建

2)Series和DataFrame的索引、切片、过滤,算术运算与数据对齐,函数映射,排序等

3)Series和DataFrame的汇总和计算统计描述

4)Series和DataFrame的层次化索引

本篇博客主要讲述Series和DataFrame的基本功能,包括索引、切片、过滤,算术运算与数据对齐,函数映射,排序等,内容安排如下所示:

1)重新索引

2)丢弃指定轴上的项

3)索引、选取和过滤

4)算术运算和数据对齐

5)函数应用和映射

6)排序

7)带有重复值的轴索引

1)重新索引

该功能主要是为了解决什么问题呢?应该是时间序列这样的数据,有时间点缺失的填充问题。主要的实例方法是.reindex(),可以处理Series和DataFrame类型的数据重新索引。

import pandas as pd
from pandas import Series,DataFrame

objSeries1 = Series(range(6),index = ['a','d','e','f','g','h'])

objSeries1
    a    0
d 1
e 2
f 3
g 4
h 5
dtype: int64
objSeries2 = objSeries1.reindex(['a','b','c','d','e','f','g','h'])

objSeries2#系统自动在缺失索引填充NaN
    a    0.0
b NaN
c NaN
d 1.0
e 2.0
f 3.0
g 4.0
h 5.0
dtype: float64
objSeries1
    a    0
d 1
e 2
f 3
g 4
h 5
dtype: int64
objSeries1.reindex(['a','b','c','d','e','f','g','h'],fill_value = 10)
    a     0
b 10
c 10
d 1
e 2
f 3
g 4
h 5
dtype: int64
objSeries1
    a    0
d 1
e 2
f 3
g 4
h 5
dtype: int64

注意,reindex不改变原数据

reindex函数的参数如下表所示:

参数 说明
index 用作索引的新序列,既可以是Index实例,也可以是其他序列的python数据结构,Index会被完全使用
method 插值(填充)方式,具体参数请见下表
fill_value 在重新索引的过程中,需要引入缺失值时使用的替代值
limit 前向和后向填充时的最大填充量
level 在MultiIndex的指定级别上匹配简单索引,否则选取其子集
copy 默认为True,无论如何都到赋值,如果为False,则新旧相等就不复制?(不太懂)

对于时间序列的有序数据,重新索引时可以做一些插值处理。method方法可以达到此目的,method插值选项如下表所示:

参数 说明
ffill或pad 前向填充
bfill或backfill 后向填充
objSeries3 = Series(['a','b','c'],index = [0,2,4])

objSeries3.reindex(range(6),method = 'ffill')
    0    a
1 a
2 b
3 b
4 c
5 c
dtype: object
objSeries3
    0    a
2 b
4 c
dtype: object

下面来看一下DataFrame的重新索引,对于DataFrame,reindex可以修改行、列索引,也可以两个都修改,如果仅传入一列,则会重新索引行。

import numpy as np

frame = DataFrame(np.arange(9).reshape(3,3),index = ['a','b','c'],columns = ['0hio','stata','texas'])
frame
0hio stata texas
a 0 1 2
b 3 4 5
c 6 7 8
frame.reindex(['a','b','c','d'],method = 'ffill')#插值只能按行进行即纵轴(1轴)
0hio stata texas
a 0 1 2
b 3 4 5
c 6 7 8
d 6 7 8
reColumns = ['stata','utah','texas']

frame.reindex(columns = reColumns,method = 'ffill')#插值只能按行进行即纵轴(1轴)
stata utah texas
a 1 NaN 2
b 4 NaN 5
c 7 NaN 8

插值只能按行进行即纵轴(1轴)

还可以利用ix的标签索引功能

frame.ix[['a','b','c','d'],['stata','utah','texas']]
stata utah texas
a 1.0 NaN 2.0
b 4.0 NaN 5.0
c 7.0 NaN 8.0
d NaN NaN NaN

重新索引小结

1)重新索引不改变原数据,会返回新的Series或者DataFrame

2)插值只能按行进行即纵轴(1轴)

2)丢弃指定轴上的项

采用drop方法返回一个在指定轴上删除指定值的新对象

#Series对象
objSeries2
    a    0.0
b NaN
c NaN
d 1.0
e 2.0
f 3.0
g 4.0
h 5.0
dtype: float64
objSeries2.drop(['b','c'])
    a    0.0
d 1.0
e 2.0
f 3.0
g 4.0
h 5.0
dtype: float64
objSeries2
    a    0.0
b NaN
c NaN
d 1.0
e 2.0
f 3.0
g 4.0
h 5.0
dtype: float64
objSeries2New = objSeries2.drop(['b','c'])
objSeries2New
    a    0.0
d 1.0
e 2.0
f 3.0
g 4.0
h 5.0
dtype: float64
objSeries2New['d'] = 6
objSeries2New
    a    0.0
d 6.0
e 2.0
f 3.0
g 4.0
h 5.0
dtype: float64
objSeries2New.sort_values()
    a    0.0
e 2.0
f 3.0
g 4.0
h 5.0
d 6.0
dtype: float64
objSeries2New
    a    0.0
d 6.0
e 2.0
f 3.0
g 4.0
h 5.0
dtype: float64
objSeries2
    a    0.0
b NaN
c NaN
d 1.0
e 2.0
f 3.0
g 4.0
h 5.0
dtype: float64

注意删除不改变原数据,返回一个新对象,新对象不是原对象的引用

#DataFrame对象

frame
0hio stata texas
a 0 1 2
b 3 4 5
c 6 7 8
frame.drop('b')
0hio stata texas
a 0 1 2
c 6 7 8
frame.drop(['0hio','stata'],axis=1)#删除纵轴时,需要指定axis=1
texas
a 2
b 5
c 8

注意删除DataFrame时,需要指定axis=1

3)索引、选取和过滤

对Series对象的索引、选取和过滤

主要分为三部分:1)根据索引号或者顺序整数索引,选取一个value;2)根据切片选取连续几个values;3)逻辑过滤

objSeries1
    a    0
d 1
e 2
f 3
g 4
h 5
dtype: int64

1)根据索引号或者顺序整数索引

objSeries1[2]
   2
objSeries1['d']
    1

2)根据切片选取连续几个values

objSeries1[2:5]#不包含5
    e    2
f 3
g 4
dtype: int64
objSeries1['e':'h']#包含末端5
    e    2
f 3
g 4
h 5
dtype: int64

注意,Series的索引切片和numpy的整数索引有所不同,Series索引切片包含末端,而numpy整数索引切片不包含

3)逻辑过滤

objSeries1[objSeries1>3]
    g    4
h 5
dtype: int64

对DatatFrame对象的索引、选取和过滤

对DatatFrame对象的进行索引就是获得一个或多个列,主要分为三部分:1)根据列索引号或者顺序整数索引切片,某一列或多列,行可以通过切片选择多行;2).ix行列索引;3)逻辑过滤

1)根据列索引号或者顺序整数索引切片,某一列或多列,行可以通过切片选择多行

frame
0hio stata texas
a 0 1 2
b 3 4 5
c 6 7 8
frame['0hio']
    a    0
b 3
c 6
Name: 0hio, dtype: int32
frame[:1]
0hio stata texas
a 0 1 2
frame['0hio':'texas']
0hio stata texas
a 0 1 2
b 3 4 5
c 6 7 8

注意,类似frame[1]进行行列选择是错误的需用.ix

2).ix行列索引

frame.ix[1,1]
    4
frame.ix[1]
    0hio     3
stata 4
texas 5
Name: b, dtype: int32
frame.ix[['a','b'],['0hio','stata']]
0hio stata
a 0 1
b 3 4
frame.ix[0:2]
0hio stata texas
a 0 1 2
b 3 4 5
frame.ix['a':'b','0hio':'stata']
0hio stata
a 0 1
b 3 4

3)逻辑过滤

frame < 4
0hio stata texas
a True True True
b True False False
c False False False
frame[frame < 4]
0hio stata texas
a 0.0 1.0 2.0
b 3.0 NaN NaN
c NaN NaN NaN
frame[frame < 4] = 0
frame
0hio stata texas
a 0 0 0
b 0 4 5
c 6 7 8
frame.ix[frame.stata > 3,:2]
0hio stata
b 0 4
c 6 7

4)算术运算和数据对齐

pandas自动的数据对齐操作在不重叠索引处引入NA值。缺失值会在算术运算中传播

objSeries1
    a    0
d 1
e 2
f 3
g 4
h 5
dtype: int64
objSeries2
    a    0.0
b NaN
c NaN
d 1.0
e 2.0
f 3.0
g 4.0
h 5.0
dtype: float64
objSeries2['b':'c'] = 10
objSeries2
    a     0.0
b 10.0
c 10.0
d 1.0
e 2.0
f 3.0
g 4.0
h 5.0
dtype: float64
objSeries4 = objSeries2['a':'f']
objSeries4
    a     0.0
b 10.0
c 10.0
d 1.0
e 2.0
f 3.0
dtype: float64
##结果,pandas自动的数据对齐操作在不重叠索引处引入NA值。缺失值会在算术运算中传播
objSeries1 + objSeries4
    a    0.0
b NaN
c NaN
d 2.0
e 4.0
f 6.0
g NaN
h NaN
dtype: float64
frame
0hio stata texas
a 0 0 0
b 0 4 5
c 6 7 8
frame1 = frame.ix['a':'b',:2]
frame1
0hio stata
a 0 0
b 0 4
frame1['add'] = 10
frame1
0hio stata add
a 0 0 10
b 0 4 10
frame1.ix['f'] = 12
frame2 = frame.drop('f')
frame2
0hio stata texas
a 0 0 0
b 0 4 5
c 6 7 8
frame2 + frame1
0hio add stata texas
a 0.0 NaN 0.0 NaN
b 0.0 NaN 8.0 NaN
c NaN NaN NaN NaN
f NaN NaN NaN NaN
frame2.add(frame1,fill_value = 0)
0hio add stata texas
a 0.0 10.0 0.0 0.0
b 0.0 10.0 8.0 5.0
c 6.0 NaN 7.0 8.0
f 12.0 12.0 12.0 NaN
frame1.add(frame2,fill_value = 0)#不知道什么情况不没有完全补充0??
0hio add stata texas
a 0.0 10.0 0.0 0.0
b 0.0 10.0 8.0 5.0
c 6.0 NaN 7.0 8.0
f 12.0 12.0 12.0 NaN

常用的算术运算

方法 说明
add 加法
sub 减法
div 除法
mul 乘法
frame
0hio stata texas
a 0 0 0
b 0 4 5
c 6 7 8
f 12 12 12
objSeries4
    a     0.0
b 10.0
c 10.0
d 1.0
e 2.0
f 3.0
dtype: float64
frame - objSeries4
0hio a b c d e f stata texas
a NaN NaN NaN NaN NaN NaN NaN NaN NaN
b NaN NaN NaN NaN NaN NaN NaN NaN NaN
c NaN NaN NaN NaN NaN NaN NaN NaN NaN
f NaN NaN NaN NaN NaN NaN NaN NaN NaN
frame.sub(objSeries4,axis = 0)#利用算术运算,可以改变轴向
0hio stata texas
a 0.0 0.0 0.0
b -10.0 -6.0 -5.0
c -4.0 -3.0 -2.0
d NaN NaN NaN
e NaN NaN NaN
f 9.0 9.0 9.0

5)函数应用和映射

numpy的ufunc函数(元素级数组方法)也可以用于操作pandas对象,

此外,还有apply()作用于DataFrame的一列(纵轴)或一行(横轴)、applymap()函数作用于DataFrame元素级

frame
0hio stata texas
a 0 0 0
b 0 4 5
c 6 7 8
f 12 12 12
frame[frame < 4] =4
frame
0hio stata texas
a 4 4 4
b 4 4 5
c 6 7 8
f 12 12 12
np.sqrt(frame)
0hio stata texas
a 2.000000 2.000000 2.000000
b 2.000000 2.000000 2.236068
c 2.449490 2.645751 2.828427
f 3.464102 3.464102 3.464102
frame.apply(lambda x:x.max() - x.min())
    0hio     8
stata 8
texas 8
dtype: int64
func = lambda x:x.max() - x.min()

frame.apply(func,axis = 0)#纵轴
    0hio     8
stata 8
texas 8
dtype: int64
frame.apply(func,axis = 1)#横轴
    a    0
b 1
c 2
f 0
dtype: int64
frame
0hio stata texas
a 4 4 4
b 4 4 5
c 6 7 8
f 12 12 12
format = lambda x:'%0.2f'%x
frame.applymap(format)
0hio stata texas
a 4.00 4.00 4.00
b 4.00 4.00 5.00
c 6.00 7.00 8.00
f 12.00 12.00 12.00
#Series也有map方法
frame.stata.map(format)
    a     4.00
b 4.00
c 7.00
f 12.00
Name: stata, dtype: object

6)排序

排序的方法有很多,主要有以下几种:

1)python内置的sorted()

2)numpy里的.sort()或np.sort()

3)pandas里的.sort_index(),.sort_values()

4)Series中的.order()

注意不同工具包返回的结果类型不一样

objSeries4
    a     0.0
b 10.0
c 10.0
d 1.0
e 2.0
f 3.0
dtype: float64
objSeries4.sort_index()
    a     0.0
b 10.0
c 10.0
d 1.0
e 2.0
f 3.0
dtype: float64
objSeries4.sort_values()
    a     0.0
d 1.0
e 2.0
f 3.0
b 10.0
c 10.0
dtype: float64
frame3 = frame.reindex(['a','c','f','b']).reindex(columns = ['texas','0hio','stata'])#多了一个轴向的选择
frame3
texas 0hio stata
a 4 4 4
c 8 6 7
f 12 12 12
b 5 4 4
frame3.sort_index(axis=0)#纵轴(行索引)排序
texas 0hio stata
a 4 4 4
b 5 4 4
c 8 6 7
f 12 12 12
frame3.sort_index(axis = 1)#横轴(列索引)排序
0hio stata texas
a 4 4 4
c 6 7 8
f 12 12 12
b 4 4 5
frame3
texas 0hio stata
a 4 4 4
c 8 6 7
f 12 12 12
b 5 4 4
frame3.sort_values(by='stata')#默认纵轴
texas 0hio stata
a 4 4 4
b 5 4 4
c 8 6 7
f 12 12 12
frame3
texas 0hio stata
a 4 4 4
c 8 6 7
f 12 12 12
b 5 4 4

注意,.sort_index、.sort_values不改变原数据,此外,注意DaraFrame的平级关系,即对某一列排序,其他列也会跟着变化

frame3.ix['c'].order()#实现横轴方向排序。
C:\Program Files\anaconda\lib\site-packages\ipykernel\__main__.py:1: FutureWarning: order is deprecated, use sort_values(...)
if __name__ == '__main__':
    0hio     6
stata 7
texas 8
Name: c, dtype: int64

7)带有重复值的轴索引

pandas允许出现重复的轴索引,那么怎么处理重复轴索引问题呢?.is_unique()可以检测出索引是否是唯一的,而利用重复轴索引时,会返回多行多列

obj = Series(range(5),index = ['a','a','b','b','c'])
obj
    a    0
a 1
b 2
b 3
c 4
dtype: int64

obj.index.is_unique
    False
obj['a']
    a    0
a 1
dtype: int64

df = DataFrame(np.random.randn(4,3),index = ['a','a','b','b'])
df
0 1 2
a -0.224366 0.250954 -0.733037
a 0.973195 -0.246500 0.895259
b 1.889028 0.229811 2.205712
b 1.407430 1.379889 0.533036
df.index.is_unique
    False
df.ix['a']
0 1 2
a -0.224366 0.250954 -0.733037
a 0.973195 -0.246500 0.895259

总结

pandas的数据处理总是不改变原数据,而是返回新的结果。