• AI算法工程师 | 03人工智能基础-Python科学计算和可视化(三)Pandas


    Python 之 数据处理分析模块 Pandas

    Pandas 是基于 Numpy 的一套数据分析工具,该工具是为了解决数据分析任务而创建的。

    • 数据模型繁多:Pandas 纳入了大量标准的数据模型,提供了高效地操作大型数据集所需的工具;
    • 导入数据方便:Pandas 可以从各种文件格式中导入数据,如:CSV、JSON、SQL、Excel 等;
    • 处理数据便捷:Pandas 是 Python 语言的一个扩展程序库,提供了许多快速便捷地处理数据的函数和方法。

    小贴士

    一、Pandas 开发环境搭建

    说明

    • Pandas 是第三方程序库,在使用 Pandas 前需确保安装了 Pandas 库。
    • 如果使用的是 Anaconda Python 开发环境,那么 Pandas 已经被集成进 Anaconda,并不需要单独安装。(由于自己使用的是 Miniconda Python 开发环境,需要单独安装 Pandas )

    测试与安装

    若不清楚 Python 环境是否安装了 Pandas,可先测试

    • Windows电脑中按键 win + R 后输入“cmd” → 在 cmd 的命令窗口输入 python
    • 进入 python 环境中后,输入 import pandas 并回车 →
    • 若输入后提示模块没有找到“ModuleNotFoundError: No module named 'pandas'”,说明未安装 Pandas;若什么都没显示,则说明已安装。
    • 注:输入 exit() 可退出 python 环境。

    cmd 中使用 pip 命令安装 Pandas:(注意该命令是在 cmd 中,而非 python 环境中)

    # 安装命令1(不指定版本)
    pip install pandas
    
    # 安装命令2(指定下载源,这样下载得更快)
    pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple
    
    • 1
    • 2
    • 3
    • 4
    • 5

    安装完成后,可以测试一下 Pandas 是否安装成功。下面是导入 pandas 模块的语句(该语句是在 python 环境中输入),若不报错,说明 Pandas 已经安装成功了。

    # 导入 pandas 模块,并起别名为 pd 
    # 注意:每次使用 pandas 前均需写导入模块的语句
    import pandas as pd  
    
    # 扩:这是查看 pandas 库的版本号的命令
    import pandas
    pandas.__version__ # 查看版本号(命令中,version前后均分别有两个下划线)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    图示
    安装

    二、Pandas 数据类型

    Pandas 中两个重要的数据类型:SeriesDataFrame

    • Series:表示数据列表(一维)
    • DataFrame:表示二维数据集(二维)

    1. Series 对象创建

    Series 语法格式

    pandas.Series( data, index, dtype, name, copy)
    '''
    参数说明:
    · data :一组数据(ndarray 类型)
    · index:数据索引标签(若不指定,默认从 0 开始)
    · dtype:数据类型,默认会自己判断
    · name :设置名称(默认为 False)
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    示例1 - 使用列表创建

    • 使用列表创建 Series 对象
    import pandas as pd # 导包
    data = pd.Series([1,2,3,4,5]) # 返回一个序列
    data
    
    • 1
    • 2
    • 3

    结果

    Series 对象本质上是调用 numpy 创建了一个一维数组,之后在其身上赋予了一个索引,从而组成了一个 Series。即:Series 对象中有 ① numpy 数组、② index 索引。

    因此,pandas 中有两个重要的属性 values(Series 对象的原始数据) 和 index(对应 Series 对象的索引对象)

    • Series 对象中两个重要的属性 values 和 index
    data.values # 查看属性 values
    data.index # 查看属性 index
    
    • 1
    • 2

    结果

    • 若不想让索引从 0 开始,可以指定索引值(index 属性)
    data = pd.Series([4,3,6,7,9],index=['one','two','three','four','five'])
    data
    
    • 1
    • 2

    结果

    • 也可使用 list 列表指定 index 属性
    data = pd.Series([4,3,6,7,9],index=list('abcde'))
    data
    
    • 1
    • 2

    结果

    示例2 - 使用字典创建

    • 使用字典创建 Series 对象
    import pandas as pd # 导包
    
    # 使用字典创建 Series 对象,默认将 key 作为 index 属性
    
    population_dict={'bj':3000,'gz':1500,'sh':2800,'sz':1200} # 可传字典
    population_series=pd.Series(population_dict)
    population_series
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    结果

    • 用字典创建 Series 对象,可指定 index 属性值。若 key 不存在,则值为 NaN(代表空值)
    # 如果存在取交集
    sub_series=pd.Series(population_dict,index=['bj','sh']) 
    sub_series
    
    • 1
    • 2
    • 3
    # 如果不存在则值为 NaN
    sub_series=pd.Series(population_dict,index=['bj','xa'])
    sub_series
    
    • 1
    • 2
    • 3

    结果

    示例3 - 使用标量与 index 创建

    • 标量与 index 属性创建 Series 对象
    import pandas as pd # 导包
    
    data = pd.Series(6,index=[6,5,8,9,3])
    data
    
    • 1
    • 2
    • 3
    • 4

    结果

    2. DataFrame 对象创建

    关于 DataFrame

    DataFrame 可以看成一个数据框(表格),有行与列。其中,每一列可以是不同的值类型,如:数值、布尔、字符串等。

    图示 - 由 Series 组成的 DataFrame:
    图示

    DataFrame 语法格式:

    pandas.DataFrame( data, index, columns, dtype, copy)
    '''
    参数说明:
    · data   :一组数据(ndarray、series, map, lists, dict 等类型)
    · index  :数据索引标签(相当于:行索引)
    · columns:列索引(默认为 RangeIndex 0, 1, 2, …, n)
    · dtype  :数据类型
    · copy   :拷贝数据(默认为 False)
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    示例1 - 使用 Series 及字典创建

    • 将两个 Series 对象作为字典的值,就可以创建一个 DataFrame 对象
    import pandas as pd # 导包
    
    # 字典
    population_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}
    area_dict={'beijing':300,'guangzhou':200,'shanghai':180}
    
    # 创建 2 个 series
    population_series=pd.Series(population_dict)
    area_series=pd.Series(area_dict)
    
    # 通过 DataFrame 创建数据框
    citys=pd.DataFrame({'area':area_series,'population':population_series})
    citys
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    结果

    • 查看 DataFrame 对象的 values、index 和 columns 属性
    citys.index # 数据索引标签(相当于:行索引)
    citys.values # 数据值
    citys.columns # 列索引
    
    • 1
    • 2
    • 3

    结果

    示例2 - 使用列表创建

    • 既然可以用列表创建 Series 对象,那是不是也可以使用列表创建 DataFrame 对象呢?
    import pandas as pd # 导包
    
    # 字典
    population_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}
    area_dict={'beijing':300,'guangzhou':200,'shanghai':180}
    
    # 使用列表创建 DataFrame 对象
    citys=pd.DataFrame([population_dict,area_dict]) # 直接把两个字典放在列表中
    citys # 会将‘beijing’‘shanghai’ ‘guangzhou’作为表头(列索引)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果

    从结果中可以看到,使用列表创建的 DataFrame 对象,若未指定 index,则行索引默认从 0 开始。

    • 使用列表创建 DataFrame 对象,可通过指定 index 设置行索引
    import pandas as pd # 导包
    
    # 字典
    population_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}
    area_dict={'beijing':300,'guangzhou':200,'shanghai':180}
    
    # 创建 DataFrame 对象,并设置行索引
    citys=pd.DataFrame([population_dict,area_dict], index=['population','area']) # 指定索引号名称
    citys
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果

    • 对于上方的代码而言,可通过指定 columns,实现取某列(或过滤)的效果
    pd.DataFrame([population_dict,area_dict], 
                 index=['population','area'],columns=['beijing','guangzhou']) # 指定 columns,设置列索引
    
    • 1
    • 2

    结果

    • 创建 DataFrame 对象,并通过指定 columns 设置列索引
    import pandas as pd # 导包
    
    # 创建 1 个 series
    population_dict={'beijing':3000,'shanghai':1200,'guangzhou':1800}
    population_series=pd.Series(population_dict)
    
    # 设置列索引
    pd.DataFrame(population_series,columns=['population']) # 指定列名
    # pd.DataFrame({'population':population_series}) # 与上一行的代码等价
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果

    • 使用列表创建 Dataframe 对象
    import pandas as pd # 导包
    
    pd.DataFrame([{'a':i,'b':i*2} for i in range(3)])
    # pd.DataFrame([{'a':i,'b':i*2} for i in range(3)], index=['一','二','三']) # 指定行名称
    
    • 1
    • 2
    • 3
    • 4

    结果

    示例3 - 使用二维数组创建

    • 使用一个二维数组并指定 columns 和 index 创建 DataFrame 对象
    import pandas as pd # 导包
    import numpy as np
    
    # 指明行名称、列名称
    pd.DataFrame(np.random.randint(0, 100, (4,3)), index=['a','b','c','d'], columns=['a','b','c']) 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    结果

    示例4 - 使用字典创建

    • 创建一个数据集
    import pandas as pd # 导包
    
    pd.DataFrame({
        'Name':['zs','lisi','ww'],
        'Sno':['1001','1002','1003'],
        'Sex':['man','woman','man'],
        'Age':[17,18,19],
        'Score':[80,97,95]
    })
    data # 字典中所有的键都作为表头(列索引)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果

    • 指定列索引
    import pandas as pd # 导包
    
    data = pd.DataFrame({
        'Name':['zs','lisi','ww'],
        'Sno':['1001','1002','1003'],
        'Sex':['man','woman','man'],
        'Age':[17,18,19],
        'Score':[80,97,95]
    },columns=['Sno','Sex','Age','Score'])
    data
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果

    • 指定行索引与列索引
    import pandas as pd # 导包
    
    data = pd.DataFrame({
        'Name':['zs','lisi','ww'],
        'Sno':['1001','1002','1003'],
        'Sex':['man','woman','man'],
        'Age':[17,18,19],
        'Score':[80,97,95]
    },columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])
    data
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果

    小贴士:

    3. 获取 Series 对象的值

    示例

    • Series 对象的切片与索引
    import pandas as pd # 导包
    
    data = pd.Series([45,6,2,3,5],index=list('abcde'))
     
    display('根据key获取:',data['a'])
    display('切片获取:',data['a':'d']) # 注意,这里(标签索引)不是左闭右开,会取到 d
    display('索引获取:',data[1]) # 取第二个
    display('索引切片:',data[2:4])# 这里(位置索引)取值时,是左闭右开
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果

    可以看到,Series 和 ndarray 数组类似,可以通过索引来访问元素。但 Series 对象的索引可分为位置索引和标签索引。

    其中,标签索引进行切片时:左闭右闭;而位置索引:左闭右开。

    • 当 Series 对象的标签索引和位置索引存在相同时,无法区分是按哪种索引获取,怎么办?
    data=pd.Series([5,6,7,8],index=[1,2,3,4])
    data[1]  
    
    • 1
    • 2

    结果

    上方的 Series 对象 data 中,位置索引与标签索引有相同值 1,则 data[1] 代表的含义便不明确,此时需使用 loc(标签索引)、iloc(位置索引)。

    • 使用 Series 对象中 loc 与 iloc 获取值
    data.loc[1] # 根据名字(标签索引)取值
    data.iloc[1] # 根据位置索引取值
    
    • 1
    • 2

    结果

    4. 获取 DataFrame 的值

    获取 DataFrame 的值的介绍

    DataFrame 对象获取的数据:

    • 可传入具体的列名 —— 通过列名选择数据的方式叫做普通索引
    • 还可以传入具体列的位置( iloc 方法)—— 传入列的位置选择数据的方式叫做位置索引

    其中,获取连续的某几列时,用普通索引和位置索引都可以做到。由于要获取的列是连续的,所以需要对列进行切片来获取数据。

    获取的方式主要有两种:

    • 一种是普通索引,即传入具体行索引的名称,需要用到 loc 方法;
    • 另外一种是位置索引,即传入具体的行数,需要用到 iloc 方法。

    示例1 - 获取列

    • 创建 DataFrame 对象
    import pandas as pd # 导包
    import numpy as np
    
    data=pd.DataFrame(np.arange(12).reshape(3,4),index=list('abc'),columns=list('ABCD'))
    data
    
    • 1
    • 2
    • 3
    • 4
    • 5

    结果

    • 获取列:① 传入具体的列名
    print('获取‘B’列:')
    print(data['B']) # 如果要获取一列,则只需要传入一个列名
    print('获取‘A’‘C’两列:')
    print(data[['A','C']]) # 如果是同时选择多列,则传入多个列名(用一个 list 存放)即可
    
    • 1
    • 2
    • 3
    • 4

    结果

    • 获取列:② 传入具体列的位置
    print('获取第 1 列:')
    print(data.iloc[:,0])
    print('获取第 1 列和第 3 列:')
    print(data.iloc[:,[0,2]])
    
    # 说明:iloc 后的方括号中
    # ① 逗号之前的部分表示要获取的行的位置。只输入一个冒号,不输入任何数值表示获取所有的行;
    # ② 逗号之后的方括号表示要获取的列的位置,列的位置同样也是从 0 开始计数。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果

    • 获取连续的几列(切片获取)
    print('获取 A B 两列,使用位置索引获取:')
    print(data.iloc[:,0:2])
    print('获取 A B C 三列,使用普通索引获取:')
    print(data.loc[:,'A':'C'])
    
    • 1
    • 2
    • 3
    • 4

    结果

    示例2 - 获取行

    • 获取某一行或某几行
    print('获取 a 行,普通索引获取:')
    print(data.loc['a'])
    print('获取 a c 行,普通索引获取:')
    print(data.loc[['a','c']])
    print('获取第 1 行,位置索引获取:')
    print(data.iloc[0])
    print('获取第 1 行第 3 行,位置索引获取:')
    print(data.iloc[[0,2]])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    结果

    • 获取连续的几行(切片获取)
    # 选择连续的某几行和选择连续某几列类似:把连续行的位置用一个区间表示
    
    print('选择第 1 行 第 2 行,使用位置索引:')
    print(data.iloc[0:2])
    print('选择 a 行 b 行,使用普通索引:')
    print(data.loc['a':'b'])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    结果

    示例3 - 同时获取行和列

    • 同时选择连续的部分行和部分列
    print('同时获取 a b c 行,A B 列,使用普通索引:')
    print(data.loc['a':'c','A':'B'] )
    print('同时获取 a b 行,A B 列,使用位置索引:')
    print(data.iloc[0:2,0:2])
    
    • 1
    • 2
    • 3
    • 4

    结果

    • 同时选择不连续的部分行和部分列
    print('同时获取 a c 行,ABD 列,使用普通索引:')
    print(data.loc[['a','c'],['A','B','D']])
    print('同时获取 a c 行,ABD 列,使用位置索引:')
    print(data.iloc[[0,2],[0,1,3]])
    
    • 1
    • 2
    • 3
    • 4

    结果

    5. Series 的方法

    Series 对象中有很多常用的方法可以对数据进行各种处理。例如:

    方法描述
    mean对某一列数据取平均数
    min获取最小值
    max获取最大值
    std获取标准差

    示例 - 对数据集进行各种运算,并排序

    • 创建一个数据集
    import pandas as pd # 导包
    
    data = pd.DataFrame({
        'Name':['zs','lisi','ww'],
        'Sno':['1001','1002','1003'],
        'Sex':['man','woman','man'],
        'Age':[17,18,19],
        'Score':[80,97,95]
    },columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])
    display('数据集',data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果

    • 计算平均值、最大值、最小值、标准差
    ages = data['Age'] # 获取数据集中 Age 列的所有
    print(ages)
    
    ages.mean(), ages.min(), ages.max(), ages.std()
    
    • 1
    • 2
    • 3
    • 4

    结果

    • 排序(正序)
    ages.sort_values() # 对 Age 列进行排序(默认正序排序)
    
    • 1

    结果

    • 降序排序
    ages.sort_values(ascending=False) #  对 Age 列进行降序排序
    
    • 1

    结果

    6. Series 的条件过滤

    Series 对象也可像 SQL 语句一样,通过指定条件进行数据的过滤。

    示例

    • 筛选出成绩大于平均值的数据
    import pandas as pd # 导包
    
    # 创建数据集
    data = pd.DataFrame({
        'Name':['zs','lisi','ww'],
        'Sno':['1001','1002','1003'],
        'Sex':['man','woman','man'],
        'Age':[17,18,19],
        'Score':[80,97,95]
    },columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])
     
    # 取出 'Score' 列的数据,并对数据进行筛选
    scores = data['Score']
    print(scores.mean()) # 平均值
    scores[scores>scores.mean()] # 筛选出大于平均值的
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    结果

    7. DataFrame 的条件过滤

    DataFrame 与 Series 类似,也可使用条件进行过滤。

    示例

    • 一个条件进行筛选:输出数据中所有成绩大于平均值的记录
    import pandas as pd # 导包
    
    # 创建数据集
    data = pd.DataFrame({
        'Name':['zs','lisi','ww'],
        'Sno':['1001','1002','1003'],
        'Sex':['man','woman','man'],
        'Age':[17,18,19],
        'Score':[80,97,95]
    },columns=['Sno','Sex','Age','Score'],index=['zs','lisi','ww'])
     
    # 输出数据中所有成绩大于平均值的记录
    scores = data['Score'] # 取出 'Score' 列的数据
    print(scores.mean())
    data[scores>scores.mean()] # data 中取值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    结果

    • 多个条件进行筛选
    # 且
    ages = data['Age'] # 获取数据集中 Age 列的所有
    data[(scores>scores.mean()) & (ages<19)] # 成绩大于平均值,且 年龄小于 19
    
    • 1
    • 2
    • 3
    # 或
    data[(scores>scores.mean()) | (ages<19)] # 成绩大于平均值,或 年龄小于 19
    
    • 1
    • 2

    结果

    • 根据条件进行筛选后,再通过 loc 取值
    # 获取成绩大于平均值的所有记录,只显示 Sno Age Score 三列
    data[scores>scores.mean()].loc[:,['Sno','Age','Score']] 
    
    • 1
    • 2

    结果

    三、处理缺失值

    何谓缺失值?缺失值是指由某些原因导致部分数据为空。

    对于为空的这部分数据,一般有两种处理方式:

    • 方式一:删除,即把含有缺失值的数据删除;
    • 方式二:填充,即把缺失的那部分数据用某个值代替。

    1. 缺失值查看

    在对缺失值进行处理前,需要把缺失值找出来,即查看哪列有缺失值。

    Pandas 中缺失值用 NaN 表示,通过调用 info() 方法可看到返回的每一列的缺失情况。

    示例

    • info() 方法查看缺失值
    import pandas as pd # 导包
    import numpy as np
    
    df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])
    df.info() # 缺失值查看 
    
    • 1
    • 2
    • 3
    • 4
    • 5

    结果

    • isnull() 方法可判断哪个值是缺失值,若为缺失值则返回 True,否则返回 False
    import pandas as pd # 导包
    import numpy as np
    
    data=pd.Series([3,4,np.nan,1,5,None])
    print(data.isnull(),'\n') # isnull()方法判断是否是缺值
    print(data[data.isnull()],'\n') # 获取缺值
    print(data[data.notnull()]) # 获取非空值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    结果

    2. 缺失值删除

    缺失值分为两种:

    • 一种是:一行中某个字段是缺失值;
    • 另一种是:一行中的字段全部为缺失值,即为一个空白行。

    调用 dropna() 方法删除缺失值:

    • dropna() 方法默认删除含有缺失值的行,即只要某一行有缺失值就把这一行删除;
    • 如果想按列为单位删除缺失值,需要传入参数 axis=’columns’

    示例

    • dropna() 方法删除缺失值
    import pandas as pd # 导包
    import numpy as np
    
    df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]]) # 3行 3列
    
    new_df = df.dropna() # 缺失值删除(默认为以行为单位剔除)
    new_df
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    结果

    • 按列进行删除缺失值(传入参数 axis=’columns’)
    df.dropna(axis='columns') # 以列为单位剔除
    
    • 1

    结果

    • 若想删除空白行,需给 dropna() 方法中传入参数 how=’all’ ,默认值为 any
    df.dropna(how='all') # 某行中所有数据为 nan 时才剔除该行
    
    • 1

    结果

    3. 缺失值填充

    由于数据是宝贵的,一般情况下如果数据缺失比例不高,尽量不会选择删除,而是选择填充。

    调用 fillna() 方法填充缺失值:

    • 在 fillna() 方法中输入要填充的值,可对数据表中的所有缺失值进行填充;
    • 还可以通过 method 参数使用前一个数和后一个数来进行填充。

    示例

    • Series 对象缺失值填充
    import pandas as pd # 导包
    import numpy as np
    
    data=pd.Series([3,4,np.nan,1,5,None])
    print('以 0 进行填充:')
    display(data.fillna(0))
    print('以前一个数进行填充:')
    display(data.fillna(method='ffill'))
    print('以后一个数进行填充:')
    display(data.fillna(method='bfill'))
    print('先按后一个,再按前一个')
    display(data.fillna(method='bfill').fillna(method='ffill')) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    结果

    • DataFrame 对象缺失值填充
    import pandas as pd # 导包
    import numpy as np
    
    df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])
    print('使用数值 0 来填充:')
    display(df.fillna(0))
    print('使用行的前一个数来填充:')
    display(df.fillna(method='ffill'))
    print('使用列的后一个数来填充:')
    display(df.fillna(method='bfill' ,axis=1)) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果

    • 使用列的平均值进行填充(常用)
    import pandas as pd # 导包
    import numpy as np
    
    df=pd.DataFrame([[1,2,np.nan],[4,np.nan,6],[5,6,7]])
    display(df) # 原数据 df
    
    for i in df.columns:
        df[i]=df[i].fillna(np.nanmean(df[i])) # 将填充完后的序列赋值给原序列(达到修改原数据的效果)
    display(df) # 填充后的数据 df
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    结果

    四、拼接

    示例1 - Series 对象拼接

    • 使用 concat() 方法对 Series 对象进行拼接
    import pandas as pd # 导包
    
    ser1=pd.Series([1,2,3],index=list('ABC'))
    ser2=pd.Series([4,5,6],index=list('DEF'))
    pd.concat([ser1,ser2])
    
    • 1
    • 2
    • 3
    • 4
    • 5

    结果

    示例2 - DataFrame 对象拼接

    • 多个 df 对象拼接,默认找相同的列索引进行合并
    import pandas as pd # 导包
    
    # 声明一个函数
    def make_df(cols,index):
        data={c:[str(c)+str(i) for i in index] for c in cols}
        return pd.DataFrame(data,index=index)
        
    # 调用函数,创建两个 DataFrame 对象
    df1=make_df('AB',[1,2])
    df2=make_df('AB',[3,4])
    
    # 拼接(默认找相同的列索引进行合并)
    pd.concat([df1, df2]) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    结果

    • 添加 axis 参数,可按列拼接
    pd.concat([df1, df2], axis=1) # 按列拼接,axis=1与 axis='columns' 等价
    
    • 1

    结果

    从上图结果中可以看到,多个 df 对象按列拼接时,若行索引不同,行也会往下拼接,并用 NaN 填充没有的数据。

    多个 df 对象拼接,当设置 axis=1 按列拼接时,相同的行索引会进行合并,如:

    结果

    示例3 - DataFrame 对象拼接的索引重复问题

    • 多个 df 对象拼接,索引(行索引)重复问题
    import pandas as pd # 导包
    
    # 声明一个函数
    def make_df(cols,index):
        data={c:[str(c)+str(i) for i in index] for c in cols}
        return pd.DataFrame(data,index=index)
        
    # 调用函数,创建两个 DataFrame 对象
    df1=make_df('AB',[1,2])
    df2=make_df('AB',[1,2])
    
    # 拼接(默认找相同的列索引进行合并)
    pd.concat([df1, df2]) 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    结果

    • 上方的行索引有重复,若想让结果的索引重新排放,可加 ignore_index 属性
    # 解决索引重复问题,方式 1 :加 ignore_index 属性
    pd.concat([df1,df2], ignore_index=True) 
    
    • 1
    • 2

    结果

    • 还可通过加 keys 属性,解决索引重复问题
    # 解决索引重复问题,方式 2 :加 keys 属性
    pd.concat([df1,df2],keys=['df1', 'df2'])
    
    • 1
    • 2

    结果

    示例4 - join 拼接

    • 两个 df 对象拼接,join 内连接做交集
    import pandas as pd # 导包
    
    # 声明一个函数
    def make_df(cols,index):
        data={c:[str(c)+str(i) for i in index] for c in cols}
        return pd.DataFrame(data,index=index)
        
    # 调用函数,创建两个 DataFrame 对象
    a=make_df('ABC',[1,2])
    b=make_df('BCD',[3,4])
    
    # 内连接(取列相交部分)
    pd.concat([a,b],join='inner')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    结果

    五、merge 的使用

    pandas 中 的 merge 和 concat 类似,但主要是用于两组有 key column 的数据,统一索引的数据。通常也被用在 Database 的处理当中。

    使用 merge 合并时有 4 种方式 how = [‘left’, ‘right’, ‘outer’, ‘inner’],默认为 inner。

    示例 - merge 的使用

    • 默认以 how=’inner’ 进行合并
    import pandas as pd # 导包
    
    # 创建 DataFrame 对象
    left=pd.DataFrame({'key':['k0','k1','k2','k3'],
                       'A':['A0','A1','A2','A3'],
                       'B':['B0','B1','B2','B3'],
                     }) # 通过字典方式传入3个列
    
    right=pd.DataFrame({'key':['k0','k1','k4','k3'],
                       'C':['C0','C1','C2','C3'],
                       'D':['D0','D1','D2','D3'],
                     }) 
    
    # 合并
    pd.merge(left, right) # 默认合并,此处以 'key' 作为公共部分(可能会丢数据)
    
    # 语句说明:
    # 先看left、right这两内容 是否有相同名字这一列,
    # 对相同列 key 的数据做交集,再把交集所对应的其他列数据合并到结果中去                 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    结果

    • 参数 how=’outer’ 进行合并
    pd.merge(left, right, how='outer') # 数据全部保留
    
    • 1

    结果

    • 参数 how=’left’ 进行合并
    pd.merge(left, right, how='left') # 左侧的全部保留
    
    • 1

    结果

    • 参数 how=’right’ 进行合并
    pd.merge(left, right, how='right')# 右侧的全部保留
    
    • 1

    结果


    —— 说明:本文写于 7.30~8.1,文中内容基于 python3,使用工具 Jupyter Notebook 编写的代码
    (本文中使用函数前的 np 代表 Numpy 的别名,pd 为 Pandas 的别名,每次使用前需导入相关模块)

  • 相关阅读:
    Kotlin第一弹:Kotlin详细介绍
    vite + vue3.0 + ts 项目搭建
    【DevOps】Rundeck以及Jenkins
    Qt下SVG格式图片应用
    归并排序 刷题笔记
    思科对路由器的配置
    虚拟与实际内存之间的关系
    【面试题精讲】Java超过long类型的数据如何表示
    【信息安全】浅谈三种XSS(跨站脚本攻击)的攻击流程与防御措施
    win7开机有画面进系统黑屏怎么办
  • 原文地址:https://blog.csdn.net/ThisAmy/article/details/126072931