当前位置: 首页 > 工具软件 > X-Series > 使用案例 >

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

郎俊雅
2023-12-01

内容简介

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
0hiostatatexas
a012
b345
c678
frame.reindex(['a','b','c','d'],method = 'ffill')#插值只能按行进行即纵轴(1轴)
0hiostatatexas
a012
b345
c678
d678
reColumns = ['stata','utah','texas']

frame.reindex(columns = reColumns,method = 'ffill')#插值只能按行进行即纵轴(1轴)
statautahtexas
a1NaN2
b4NaN5
c7NaN8

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

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

frame.ix[['a','b','c','d'],['stata','utah','texas']]
statautahtexas
a1.0NaN2.0
b4.0NaN5.0
c7.0NaN8.0
dNaNNaNNaN

重新索引小结

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
0hiostatatexas
a012
b345
c678
frame.drop('b')
0hiostatatexas
a012
c678
frame.drop(['0hio','stata'],axis=1)#删除纵轴时,需要指定axis=1
texas
a2
b5
c8

注意删除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
0hiostatatexas
a012
b345
c678
frame['0hio']
    a    0
    b    3
    c    6
    Name: 0hio, dtype: int32
frame[:1]
0hiostatatexas
a012
frame['0hio':'texas']
0hiostatatexas
a012
b345
c678

注意,类似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']]
0hiostata
a01
b34
frame.ix[0:2]
0hiostatatexas
a012
b345
frame.ix['a':'b','0hio':'stata']
0hiostata
a01
b34

3)逻辑过滤

frame < 4
0hiostatatexas
aTrueTrueTrue
bTrueFalseFalse
cFalseFalseFalse
frame[frame < 4]
0hiostatatexas
a0.01.02.0
b3.0NaNNaN
cNaNNaNNaN
frame[frame < 4] = 0
frame
0hiostatatexas
a000
b045
c678
frame.ix[frame.stata > 3,:2]
0hiostata
b04
c67

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
0hiostatatexas
a000
b045
c678
frame1 = frame.ix['a':'b',:2]
frame1
0hiostata
a00
b04
frame1['add'] = 10
frame1
0hiostataadd
a0010
b0410
frame1.ix['f'] = 12
frame2 = frame.drop('f')
frame2
0hiostatatexas
a000
b045
c678
frame2 + frame1
0hioaddstatatexas
a0.0NaN0.0NaN
b0.0NaN8.0NaN
cNaNNaNNaNNaN
fNaNNaNNaNNaN
frame2.add(frame1,fill_value = 0)
0hioaddstatatexas
a0.010.00.00.0
b0.010.08.05.0
c6.0NaN7.08.0
f12.012.012.0NaN
frame1.add(frame2,fill_value = 0)#不知道什么情况不没有完全补充0??
0hioaddstatatexas
a0.010.00.00.0
b0.010.08.05.0
c6.0NaN7.08.0
f12.012.012.0NaN

常用的算术运算

方法说明
add加法
sub减法
div除法
mul乘法
frame
0hiostatatexas
a000
b045
c678
f121212
objSeries4
    a     0.0
    b    10.0
    c    10.0
    d     1.0
    e     2.0
    f     3.0
    dtype: float64
frame - objSeries4
0hioabcdefstatatexas
aNaNNaNNaNNaNNaNNaNNaNNaNNaN
bNaNNaNNaNNaNNaNNaNNaNNaNNaN
cNaNNaNNaNNaNNaNNaNNaNNaNNaN
fNaNNaNNaNNaNNaNNaNNaNNaNNaN
frame.sub(objSeries4,axis = 0)#利用算术运算,可以改变轴向
0hiostatatexas
a0.00.00.0
b-10.0-6.0-5.0
c-4.0-3.0-2.0
dNaNNaNNaN
eNaNNaNNaN
f9.09.09.0

5)函数应用和映射

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

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

frame
0hiostatatexas
a000
b045
c678
f121212
frame[frame < 4] =4
frame
0hiostatatexas
a444
b445
c678
f121212
np.sqrt(frame)
0hiostatatexas
a2.0000002.0000002.000000
b2.0000002.0000002.236068
c2.4494902.6457512.828427
f3.4641023.4641023.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
0hiostatatexas
a444
b445
c678
f121212
format = lambda x:'%0.2f'%x
frame.applymap(format)
0hiostatatexas
a4.004.004.00
b4.004.005.00
c6.007.008.00
f12.0012.0012.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
texas0hiostata
a444
c867
f121212
b544
frame3.sort_index(axis=0)#纵轴(行索引)排序
texas0hiostata
a444
b544
c867
f121212
frame3.sort_index(axis = 1)#横轴(列索引)排序
0hiostatatexas
a444
c678
f121212
b445
frame3
texas0hiostata
a444
c867
f121212
b544
frame3.sort_values(by='stata')#默认纵轴
texas0hiostata
a444
b544
c867
f121212
frame3
texas0hiostata
a444
c867
f121212
b544

注意,.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
012
a-0.2243660.250954-0.733037
a0.973195-0.2465000.895259
b1.8890280.2298112.205712
b1.4074301.3798890.533036
df.index.is_unique
    False
df.ix['a']
012
a-0.2243660.250954-0.733037
a0.973195-0.2465000.895259

总结

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

 类似资料: