接上篇《59、Pandas库中Series对象的操作(二)》
上一篇我们讲解了Series对象的运算、函数应用、时间序列操作,以及Series的案例实践。本篇我们来讲解Pandas中DataFrame对象的操作。
一、DataFrame对象的基本概念及特点
在Pandas库中,DataFrame是一种非常重要的数据结构,它以一种表格的形式存储和操作结构化数据。DataFrame对象不仅继承了NumPy数组的强大功能,还提供了更为丰富的数据操作接口,使得数据分析工作变得既高效又便捷。
1、基本概念
DataFrame是Pandas中的一个二维、大小可变、异构的表格型数据结构,具有标记的轴(行和列)。你可以将其想象成一个Excel表格,其中包含了行和列,每列可以是不同的数据类型(数值、字符串、布尔值等)。DataFrame既有行索引也有列索引,这使得数据的检索和操作变得非常灵活。
2、特点
(1)异构性:DataFrame的列可以是不同的数据类型,这是与NumPy数组的主要区别之一。NumPy数组要求所有元素的数据类型必须相同,而DataFrame则没有这个限制。
(2)标签化的轴:DataFrame的轴可以被视为行和列的标签(或索引)。这使得用户可以通过标签来选择数据,而不仅仅是位置。
(3)丰富的操作接口:Pandas为DataFrame提供了大量的方法,用于数据的清洗、转换、聚合、分组以及可视化等操作。这些方法极大地简化了数据分析的流程。
(4)高效的数据处理能力:DataFrame底层使用NumPy库,因此继承了NumPy的高效性能。同时,Pandas还通过内部优化,使得大数据量的处理变得更加迅速和高效。
(5)集成性:Pandas库与Python的其他数据分析和可视化库(如Matplotlib、Seaborn、SciPy等)有着良好的集成性。用户可以方便地将DataFrame对象与这些库结合使用,进行更复杂的数据分析和可视化工作。
(6)易于理解:DataFrame的表格型结构使得数据更加直观和易于理解。对于熟悉Excel等表格软件的用户来说,DataFrame的使用门槛相对较低。
3、应用场景
DataFrame在数据分析、数据挖掘、机器学习等多个领域都有着广泛的应用。无论是处理CSV文件、Excel文件还是SQL数据库中的数据,DataFrame都能提供强大的支持。通过DataFrame,用户可以轻松地进行数据清洗、转换、聚合等操作,为后续的数据分析和建模工作打下坚实的基础。
综上所述,DataFrame是Pandas库中一个非常重要且强大的数据结构,它以其独特的特点和丰富的操作接口,在数据分析领域发挥着不可替代的作用。
二、DataFrame的创建
在Pandas中,DataFrame的创建方式多种多样,可以基于多种数据源来构建。以下详细介绍了几种常见的创建DataFrame的方法。
1、从字典创建DataFrame
(1)使用pd.DataFrame()函数
从字典创建DataFrame是Pandas中最直接的方式之一。字典的键将被用作DataFrame的列名,而字典的值(通常是列表或NumPy数组)则作为列的数据。
import pandas as pd
# 创建一个字典
data = {
'姓名': ['张三', '李四', '王五'],
'年龄': [25, 28, 34],
'性别': ['男', '女', '男']
}
# 使用pd.DataFrame()函数创建DataFrame
df = pd.DataFrame(data)
print(df)
效果:
(2)设定列索引和行索引
在创建DataFrame时,还可以指定列索引和行索引。如果数据本身包含了一个可以被用作索引的列(如ID),可以在创建DataFrame后设置其为索引。
# 设定行索引
index = ['ID001', 'ID002', 'ID003']
df = pd.DataFrame(data, index=index)
# 查看结果
print(df)
# 如果数据中有可以作为索引的列,可以在创建后设置
df.set_index('Name', inplace=True)
print(df)
效果:
注:在Pandas库中,inplace=True是一个参数,它经常出现在修改DataFrame或Series对象的方法中。这个参数的作用是控制修改是否直接在原对象上进行,还是返回一个新的对象。
2、从CSV文件创建DataFrame
(1)使用pd.read_csv()函数
CSV(逗号分隔值)文件是数据分析中常用的数据格式之一。Pandas提供了read_csv()函数来方便地从CSV文件中读取数据并创建DataFrame。
首先我们创建一个csv文件,打开一个记事本,输入下面的内容:
然后保存后,将txt格式直接修改为csv格式,打开看一下效果(用wps打开):
读取代码:
import pandas as pd
# 使用pd.read_csv()读取CSV文件
df = pd.read_csv('data.csv')
# 查看前几行数据
print(df.head())
效果:
(2)处理文件路径、分隔符、编码等参数
read_csv()函数提供了多个参数来处理不同格式的CSV文件,如filepath_or_buffer用于指定文件路径,sep或delimiter用于指定字段分隔符(默认为逗号,),encoding用于指定文件编码(如'utf-8')。
# 指定文件路径、分隔符和编码
df = pd.read_csv('data.csv', sep=';', encoding='utf-8')
# 查看数据
print(df)
效果:
这里出现这种结果,是因为我们用的是“,”号进行数据列分割,而用“;”分割的话,所有列都被识别为一列了,因为没有“;”符号可分割。
3、从其他数据源创建DataFrame(可选)
Pandas不仅支持从字典和CSV文件创建DataFrame,还支持从其他多种数据源读取数据,如Excel文件、SQL数据库等。
(1)Excel文件
按照原来的数据,准备一个xlsx(csv在wps中另存为xlsx):
使用pd.read_excel()函数可以从Excel文件中读取数据。
# 从Excel文件读取数据(先安装openpyxl库)
df = pd.read_excel('data.xlsx', sheet_name='data')
# 查看数据
print(df)
效果:
(2)SQL数据库
要使用Pandas从SQL数据库读取数据,你通常需要先安装并配置数据库连接库(如sqlite3、pymysql、psycopg2等),然后使用pd.read_sql_query()或pd.read_sql_table()等函数。
这里我们将之前测试SQLite的db数据库,拷贝到测试代码所在的文件夹下,进行连接测试:
import sqlite3
import pandas as pd
# 连接到SQLite数据库
conn = sqlite3.connect("test.db")
# 从数据库中读取数据
query_sql = "select * from users"
df = pd.read_sql_query(query_sql, conn)
# 关闭连接
conn.close()
# 查看数据
print(df)
效果:
注意:以上SQL数据库示例使用的是SQLite,对于其他类型的数据库(如MySQL、PostgreSQL等),你需要安装相应的Python库并修改连接字符串。
三、DataFrame的基本操作
1、查看DataFrame信息
在Pandas中,DataFrame是处理表格数据的主要数据结构,它提供了多种方法来查看数据的基本信息,以便于数据的分析和处理。
● 使用head(), tail()方法
head(n)方法默认返回DataFrame的前5行数据,n参数可以指定返回的行数。这对于快速查看数据的开始部分非常有用。
import pandas as pd
# 假设df是我们从上个xlsx文件中读取的DataFrame
df = pd.read_excel('data.xlsx')
# 查看前3行数据
print(df.head(3))
效果:
tail(n)方法则与head()相反,它默认返回DataFrame的最后5行数据,n参数同样可以指定返回的行数。
# 查看最后2行数据
print(df.tail(2))
效果:
● 使用info(), describe()方法
info()方法提供了DataFrame的简洁摘要,包括列名、每列的非空值数量、数据类型等信息。
# 查看DataFrame的详细信息
print(df.info())
效果:
describe()方法提供了数值列的统计汇总,包括计数、平均值、标准差、最小值、四分位数和最大值等。对于非数值列,则提供计数、唯一值数量、众数等统计信息。
# 查看数值列的统计信息
print(df.describe())
效果:
2、索引和切片
在Pandas中,索引是访问DataFrame行和列的关键。
● 使用行标签和列标签进行索引
可以直接通过列名访问单列数据,这会返回一个Series对象。
# 访问'姓名'列
print(df['姓名'])
效果:
通过行标签(索引)访问单行数据,需要结合.loc[]或.iloc[]。
● 使用.loc[]和.iloc[]进行定位
.loc[]基于标签的索引器,可以接收行标签和列标签的切片器、布尔数组、可调用对象或标签列表。
# 使用.loc[]访问第一行和'姓名', '年龄'列
print(df.loc[0, ['姓名', '年龄']])
# 访问'姓名'列中索引为0到2的行
print(df.loc[0:2, '姓名'])
效果:
.iloc[]基于位置的索引器,主要用于通过整数位置选择数据。
# 使用.iloc[]访问前两行和前两列
print(df.iloc[:2, :2])
效果:
3、选择数据
Pandas提供了灵活的方式来选择DataFrame中的特定数据。
● 选择单列或多列
如前所述,可以通过列名直接选择单列或多列。
● 选择多行或多列的数据子集
使用.loc[]或.iloc[]结合条件表达式或切片来选择多行多列的数据子集。
# 使用.loc[]选择'年龄'大于25的行和所有列
print(df.loc[df['年龄'] > 25])
效果:
● 使用布尔索引
布尔索引是一种强大的选择数据的方法,它允许你根据条件来选择满足特定条件的行。
# 选择'年龄'大于25的所有行
mask = df['年龄'] > 25
print(df[mask])
# 或者直接在一个表达式中完成
print(df[df['年龄'] > 25])
效果:
以上便是DataFrame基本操作的概述,结合实例数据可以更直观地理解和应用这些方法。
四、DataFrame的数据清洗
1、处理缺失值
● 检测缺失值
首先,我们需要检测DataFrame中的缺失值。Pandas提供了isnull()或isna()方法来检测缺失值,返回一个与原DataFrame形状相同的布尔型DataFrame,其中缺失值用True表示。
import pandas as pd
# 创建一个包含不同类型数据和缺失值的DataFrame
data = {
'编号': [1, 2, 3, 4, 5, 6],
'姓名': ['张三', '李四', '王五', '赵六', '孙七', '张三'], # 重复值
'年龄': [25, 30, np.nan, 22, 35, 25], # 缺失值
'薪资': [50000, 60000, 70000, 80000, np.nan, 50000], # 缺失值
'入职日期': ['2020-01-01', '2021-02-15', '2022-03-01', '2021-04-15', '2020-05-01', '2020-01-01'], # 日期时间字符串
'类别': ['A', 'B', 'A', 'C', np.nan, 'A'] # 分类数据,包含缺失值
}
# 将数据字典转换为DataFrame
df = pd.DataFrame(data)
# 检测缺失值
missing_values = df.isnull()
print(missing_values.head()) # 查看前几行的缺失值情况
# 统计每列缺失值的数量
missing_counts = missing_values.sum()
print(missing_counts)
效果:
● 删除含有缺失值的行或列
根据需求,我们可以选择删除含有缺失值的行或列。通常,删除列的做法比较谨慎,因为列往往代表数据的一个重要维度。
# 删除含有缺失值的行
df_dropped_rows = df.dropna(axis=0) # axis=0表示行
print(df_dropped_rows.shape) # 查看删除后的形状
# 删除含有缺失值的列(慎用)
df_dropped_cols = df.dropna(axis=1, how='any') # how='any'表示只要列中有缺失值就删除
print(df_dropped_cols.shape)
效果:
● 填充缺失值
对于数值型数据,常用均值、中位数或众数来填充缺失值。对于分类数据,可以使用众数或特定值(如"Unknown")来填充。
# 使用均值填充数值型缺失值
print('【使用均值填充数值型缺失值】')
age_mean = df['年龄'].mean()
df['年龄'] = df['年龄'].fillna(age_mean)
print(df)
# 使用中位数填充
print('【使用中位数填充数值型缺失值】')
age_median = df['薪资'].median()
df['薪资'] = df['薪资'].fillna(age_median)
print(df)
# 对于分类数据,使用众数填充(需要额外计算众数)
print('【使用众数填充分类型缺失值】')
mode_val = df['类别'].mode()[0]
df['类别'] = df['类别'].fillna(mode_val)
print(df)
# 使用固定值填充
# df['某字段'].fillna('Unknown', inplace=True)
# print(df)
效果:
2、数据类型转换
● 使用astype()方法进行数据类型转换
astype()方法允许我们将DataFrame中的列转换为指定的数据类型。
# 将字符串类型的列转换为整数类型
df['int_column'] = df['str_int_column'].astype(int)
# 注意:转换时可能会遇到无法转换的值,这时可以设置errors参数为'ignore'或'coerce'
# df['int_column'] = df['str_int_column'].astype(int, errors='coerce') # 'coerce'会将无法转换的值转换为NaN
# 转换失败时的另一种处理方式是先清洗数据
● 转换日期时间类型
Pandas提供了pd.to_datetime()函数来将字符串或其他类型的数据转换为日期时间类型。
# 假设'date_str_column'是包含日期时间字符串的列
df['date_column'] = pd.to_datetime(df['date_str_column'])
# 查看转换后的数据类型
print(df['date_column'].dtype)
3、重复值处理
● 检测重复值
duplicated()方法用于检测DataFrame中的重复值,返回一个布尔型Series,表示每行是否是重复行(第一次出现的重复行返回False,之后的重复行返回True)。
# 检测重复值,排除“编号”列
# 使用subset参数来指定除了哪些列之外的其他列都用于检测重复值
duplicates = df.duplicated(subset=df.columns.difference(['编号']))
print('【检测重复值】')
print(duplicates)
# 查看重复值的总数
print('【查看重复值的总数】')
print(duplicates.sum())
效果:
● 删除重复值
drop_duplicates()方法用于删除重复值,返回一个新的DataFrame,其中删除了指定的重复行。
# 删除所有重复的行,保留第一次出现的行
print('【删除所有重复的行,保留第一次出现的行】')
df_no_duplicates = df.drop_duplicates(subset=df.columns.difference(['编号']))
# 或者,指定子集来检测重复值
df_no_duplicates_subset = df.drop_duplicates(subset=['姓名', '年龄', '类别'])
# 查看结果
print(df_no_duplicates.shape)
效果:
至此,我们完成了DataFrame对象的简介、基本操作及数据清洗相关的内容。下一篇我们来继续讲解DataFrame对象的统计分析、可视化以及数据导出与保存相关内容。
转载请注明出处:https://guangzai.blog.csdn.net/article/details/140418261