Pandas入门篇(二)-------Dataframe篇1(Dataframe基础知识以及单个Dataframe的处理)(机器学习前置技术栈)
本篇主要演示了Dataframe 属性、Dataframe 创建、Pandas 读取和保存数据、Dataframe 数据的选择、Dataframe 的常用方法、Dataframe 修改行列索引等内容,更多知识点请期待下期
目录
概述
Dataframe是pandas库中的一个核心数据结构,用于存储和操作表格型数据。它是一个二维的、大小可变的、可以存储多种类型数据的表格型数据结构,类似于Excel中的表格或SQL中的表。Dataframe的每一列可以有不同的数据类型(如数值、字符串、布尔值等),而且行和列都有标签,这些标签可以作为数据的索引,方便用户进行数据的访问和操作。
Dataframe不仅提供了丰富的数据操作和分析功能,如数据排序、分组、聚合、合并等,还支持与其他数据结构的互操作性,如可以轻松地将Dataframe转换为NumPy数组、Python字典或SQL表等。这使得Dataframe成为数据科学、机器学习、统计分析等领域中不可或缺的工具。
总的来说,Dataframe是一个强大而灵活的数据结构,能够帮助用户高效地处理和分析大量数据,并以直观的方式展示结果。无论是数据清洗、转换还是统计分析,Dataframe都能提供便捷和强大的支持。
一、Dataframe 属性
首先我们先创建一个Dataframe
# 导入数据(以下代码均在jupyter notebook中运行)
import pandas as pd
data = pd.read_csv('/export/data/pandas_data/gapminder.tsv',sep= '\t')
# 查看数据
data
运行结果:
1. values:将DataFrame转换为NumPy数组的属性。
这个属性可以将DataFrame中的数据提取出来,转换为NumPy数组格式,方便进行数值计算和其他操作。
# 访问属性
# 将DataFrame转换为NumPy数组
values_array = data.values
print("values:\n", values_array)
运行结果:
2. axes:返回一个表示DataFrame轴的列表。
这通常包括行索引和列索引。
代码实现:
# 返回DataFrame的轴
axes_list = data.axes
print("axes:\n", axes_list)
运行结果:
3. columns:返回DataFrame的列标签。
这是一个Index对象,包含了所有列的名称。
代码实现:
# 返回列标签
columns_index = data.columns
print("columns:\n", columns_index)
运行结果:
4. dtypes:返回DataFrame中的数据类型。
这是一个Series,其索引是列,值是对应列的数据类型。
代码实现:
# 返回数据类型
dtypes_series = data.dtypes
print("dtypes:\n", dtypes_series)
运行结果:
5. empty:返回一个布尔值,表示DataFrame是否为空(即是否包含任何数据)。
代码实现:
# 检查DataFrame是否为空
is_empty = data.empty
print("empty:", is_empty)
运行结果:
6. index:返回DataFrame的行标签(索引)。
这也是一个Index对象。start为索引开始,stop为结束,step为步长
代码实现:
# 返回行标签(索引)
index_obj = data.index
print("index:\n", index_obj)
运行结果:
7. ndim:返回一个表示轴数(即数组的维数)的整数。
对于DataFrame,这通常是2,因为它是一个二维结构。
代码实现:
# 返回轴数
ndim_int = data.ndim
print("ndim:", ndim_int)
运行结果:
8. shape:返回一个表示DataFrame维数的元组。
例如,对于一个有m行和n列的DataFrame,shape将是(m, n)。
代码实现:
# 返回维数
shape_tuple = data.shape
print("shape:", shape_tuple)
运行结果:
9. size:返回一个整数,表示此对象中元素的数量。
这等于DataFrame的行数乘以列数。(代码见下方)
代码实现:
# 返回元素数量
size_int = data.size
print("size:", size_int)
运行结果:
二、Dataframe 创建
在pandas库中,创建Dataframe有多种方式。以下是几种常见的创建Dataframe的方法:
1. 从字典创建
使用字典来创建Dataframe是最常见的方法之一。字典的键将被用作列名,而字典的值(通常是列表或NumPy数组)将构成相应的列数据。
import pandas as pd
data = {
'Name': ['Alice', 'Bob', 'Charlie'],
'Age': [25, 32, 18],
'City': ['New York', 'Paris', 'London']
}
df = pd.DataFrame(data)
print(df)
运行结果:
2. 从列表的列表创建
如果你有一个列表的列表,其中内部列表表示行,那么也可以很容易地创建Dataframe。
data = [
['Alice', 25, 'New York'],
['Bob', 32, 'Paris'],
['Charlie', 18, 'London']
]
# 列表的列表需要配合列名一起使用
df = pd.DataFrame(data, columns=['Name', 'Age', 'City'])
print(df)
运行结果
3. 从NumPy数组创建
如果你已经有NumPy数组,并且希望将它们转换为Dataframe,你可以这样做。
import numpy as np
# 创建一个NumPy数组
data = np.array([
['Alice', 25, 'New York'],
['Bob', 32, 'Paris'],
['Charlie', 18, 'London']
])
# NumPy数组也需要配合列名一起使用
df = pd.DataFrame(data, columns=['Name', 'Age', 'City'])
print(df)
运行结果:
4. 从Series对象创建
你还可以使用pandas的Series对象来创建Dataframe。
# 创建几个Series对象
s1 = pd.Series(['Alice', 'Bob', 'Charlie'], name='Name')
s2 = pd.Series([25, 32, 18], name='Age')
s3 = pd.Series(['New York', 'Paris', 'London'], name='City')
# 使用字典将Series对象组合成Dataframe
df = pd.DataFrame({s1.name: s1, s2.name: s2, s3.name: s3})
print(df)
运行结果:
5. 从CSV文件创建
如果数据存储在CSV文件中,你可以使用pd.read_csv()函数来读取数据并创建Dataframe。
# 导入数据(以下代码均在jupyter notebook中运行)
import pandas as pd
data = pd.read_csv('/export/data/pandas_data/gapminder.tsv',sep= '\t')
# 查看数据
data
运行结果:
在使用pd.read_csv()时,你可以指定各种参数来控制数据的读取方式,比如分隔符、列名、编码等(下方会详细介绍)。
6. 从SQL数据库创建
如果你的数据存储在SQL数据库中,你可以使用pd.read_sql()函数配合SQLAlchemy来从数据库中读取数据并创建Dataframe。
from sqlalchemy import create_engine
import pandas as pd
# 创建数据库连接
engine = create_engine('sqlite:///mydatabase.db')
# 执行SQL查询并创建Dataframe
df = pd.read_sql('SELECT * FROM my_table', engine)
print(df)
这些只是创建Dataframe的一些常见方法。pandas库提供了丰富的功能,可以根据你的具体需求和数据源来创建和操作Dataframe。
三、Pandas 读取和保存数据
1.导入数据
格式: read_数据格式( filepath_or_buffer , sep 或 delimiter=None , header= None , names =None , index_col =None , dtype =None , skiprows = None , nrows = None , encoding = None , parse_dates = None , na_values = None)
- filepath_or_buffer:
这个参数用于指定要读取的文件路径或者类似文件的对象。
例如:pd.read_csv(‘path_to_your_file.csv’) - sep 或 delimiter:
这两个参数都是用于指定字段分隔符的。
默认为逗号 ,,但也可以指定其他分隔符,如制表符 \t 或竖线 |。 - header:
这个参数用于指定用作列名的行号。
默认为 0,表示第一行作为列名。
如果数据没有表头,可以设置为 None,pandas 会自动生成默认的列名。 - names:
当原始数据没有表头,但又想设置自定义的列名时,可以使用这个参数。
例如:names=[‘col1’, ‘col2’, ‘col3’] - index_col:
这个参数用于指定用作索引的列编号或列名。
例如,如果希望将第一列作为索引,可以设置为 0 或列名。 - usecols:
这个参数用于指定返回的列。
可以是列名的列表或由列索引组成的列表。
例如:usecols=[‘col1’, ‘col3’] 或 usecols=[0, 2] - dtype:
-传入字典格式为{‘列名1’:str,‘列名2’:int}
这个参数用于指定某些列的数据类型。
可以是一个字典或列表,将列名或列索引映射到相应的数据类型。 - skiprows:
这个参数用于指定需要忽略的行数(从文件开头算起),或需要跳过的行号列表。
例如,如果要忽略前两行,可以设置为 2 或 [0, 1]。 - nrows:
这个参数用于指定需要读取的行数(从文件开头算起)。
如果只需要读取文件的前几行,可以使用这个参数。 - skipfooter:
这个参数用于指定文件尾部需要忽略的行数。 - keep_default_na:默认为True。
是否不忽略缺失值,True的时候正常导入缺失值,False为忽略缺失值,即传入为空值(空值和缺失值在pandas里不为同一个东西) - encoding:
这个参数用于指定文件的编码方式,如 ‘utf-8’ 或 ‘latin-1’。 - parse_dates:
这个参数用于将某些列解析为日期类型。
可以是一个布尔值、列名的列表或列索引的列表,或者是一个包含列名和日期格式字符串的字典。 - na_values :
将某些字符转化为缺失值
代码实现:
# 使用 read_csv 函数读取 CSV 文件
df = pd.read_csv(
'/export/data/pandas_data/gapminder.tsv',
sep='\t', # 分隔符,默认为 ','
header=0, # 用作列名的行号,默认为 0(第一行)
names=None, # 列名列表,如果数据中没有列名则提供此参数
index_col=None, # 用作行索引的列编号或列名
dtype=None, # 数据或列的数据类型
skiprows=None, # 需要跳过的行号(从 0 开始)或要跳过的行的条件
nrows=1000, # 需要读取的行数1000
encoding='utf-8', # 文件编码
parse_dates=None, # 将列解析为日期的列号或列名的列表
na_values=['null'] # 额外的字符串或数字被识别为 NA/NaN
)
# 显示读取的数据
print(df)
运行结果
2. 导出数据
格式:to_数据格式()
- to_csv()
参数:- path_or_buf:str or file handle, default None。
文件路径或文件句柄,用于写入数据。如果为 None,则返回生成的 CSV 格式的字符串。 - sep:str, default ‘,’。
字段分隔符。默认为逗号。 - na_rep:str, default ‘’。
缺失值的表示方式。 - float_format:str, optional。
浮点数的格式字符串,例如 ‘%.2f’ 表示保留两位小数。 - columns:sequence, optional。
要写入的列。默认为 None,即写入所有列。 - header:bool or list of str, default True。
是否写入列名。如果为 True,则写入列名。如果提供了字符串列表,则假定它是列名的别名。 - index:bool, default True。
是否写入行索引。 - index_label:str or sequence, or False, default None。
如果需要,可以替换为行索引的列标签。如果为 False,则不写入行索引。 - mode:str。
文件打开模式,默认为 ‘w’。 - encoding:str, optional。
文件编码,默认为 ‘utf-8-sig’。 - compression:str or dict, optional。
压缩类型。 - quoting:int or csv.QUOTE_*, default csv.QUOTE_MINIMAL。
控制引号的使用。 - quotechar:str, default ‘"’。
用于引号的字符。 - line_terminator:str, optional。
行终止符,默认为 os.linesep。
代码实现:
- path_or_buf:str or file handle, default None。
# 创建一个简单的 DataFrame
import pandas as pd
import csv # 导入csv模块
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4.56789, 5, 6],
'C': ['foo', 'bar', 'baz with spaces'],
'D': pd.date_range('2023-01-01', periods=3)
})
# 将 DataFrame 写入 CSV 文件,使用更多参数
df.to_csv(
'output_with_more_params.csv', # 输出文件路径
sep=';', # 使用分号作为字段分隔符
na_rep='N/A', # 将缺失值表示为 'N/A'
float_format='%.2f', # 浮点数保留两位小数
columns=['A', 'C', 'D'], # 只写入 'A', 'C', 'D' 这三列
header=['Column1', 'Column3', 'DateColumn'], # 使用自定义的列名
index=False, # 不写入行索引
date_format='%Y-%m-%d', # 日期列的格式
quoting=csv.QUOTE_NONNUMERIC, # 仅对非数字值加引号
quotechar='"', # 使用双引号作为引号字符
line_terminator='\r\n', # 使用 Windows 风格的行终止符
encoding='utf-8' # 文件编码为 UTF-8
)
# 输出信息确认文件已写入
print(f"CSV file has been saved to 'output_with_more_params.csv'")
文件导出结果:
- to_excel()
参数:
- excel_writer: 文件路径或现有的 ExcelWriter 对象。
- sheet_name: 字符串,默认为 ‘Sheet1’,指定要写入的 Excel 工作表的名称。
- na_rep: 字符串,用于表示缺失数据的值。
- float_format: 字符串,用于格式化浮点数的格式。例如,‘%.2f’ 会将浮点数格式化为小数点后两位。
- columns: 列名或列名的列表,用于指定要写入的列。
- header: 布尔值或列名列表,是否写入列名到文件,或提供列名列表以覆盖原始列名。
- index: 布尔值,是否写入行索引(行标签)。
- index_label: 字符串或序列,行索引的列标签。如果未指定且 header 和 index 均为 True,则使用索引名。如果使用了 MultiIndex,则应该是一个序列。
- startrow: 从哪一行开始写入。索引从 0 开始。
- startcol: 从哪一列开始写入。索引从 0 开始。
- mode: 字符串,{‘w’, ‘a’},文件写入模式,‘w’ 为写入(会覆盖现有文件),‘a’ 为追加。
- encoding: 字符串,对于 Excel 97-2003 格式,默认编码是 ‘ascii’。对于 Excel 2007 及更高版本,使用 ‘utf-8’。
代码实现:
# 创建一个简单的 DataFrame
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4.56789, 5, 6],
'C': ['foo', 'bar', 'baz'],
'D': pd.date_range('2023-01-01', periods=3)
})
# 将 DataFrame 写入 Excel 文件的第一个工作表
df.to_excel(
'./output.xlsx', # ExcelWriter 对象
sheet_name='Sheet1', # 工作表名称
na_rep='N/A', # 缺失数据表示为 'N/A'
float_format='%.2f', # 浮点数格式化为两位小数
columns=['A', 'B', 'C'], # 只写入 'A', 'B', 'C' 这三列
header=True, # 写入列名
index=False, # 不写入行索引
startrow=0, # 从第 0 行开始写入
startcol=0, # 从第 0 列开始写入
encoding='utf-8' # 文件编码
)
print(f"Excel file has been saved to 'output.xlsx'")
运行结果:
- to_pikle()
- to_pdf()
四、Dataframe 数据的选择
1. 加载列数据
(1). 加载一列的数据
语法: **Dataframe.column** / **Dataframe['column']**
代码实现:
# 创建一个简单的 DataFrame
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4.56789, 5, 6],
'C': ['foo', 'bar', 'baz'],
'D': pd.date_range('2023-01-01', periods=3)
})
print(df)
# 加载一列数据
print(df.A)
print(df['A'])
运行结果:
(2). 加载多列数据(Dataframe[[‘column1’,‘column2’]])
代码如下:
print(df['A'])
#%%
# 创建一个简单的 DataFrame
df = pd.DataFrame({
'A': [1, 2, 3],
'B': [4.56789, 5, 6],
'C': ['foo', 'bar', 'baz'],
'D': pd.date_range('2023-01-01', periods=3)
})
print(df)
# 获取A、C、D列
print(df[['A','B','C']])
运行结果:
2. 加载行数据
(1). head(n) / tail(n)
- head() 默认获取前5条数据,传入数据n时,获取前n条数据
- tail() 默认获取后5条数据,传入数据n时,获取前n条数据
代码实现:
# head() tail()不传参数时,默认获取前5条
print(data.head())
print()
print(data.head(10))
print()
print(data.tail())
print()
print(data.tail(8))
运行结果:
(2). loc 和 iloc
- loc按索引列加载
按切片方式获取索引列时,包前也包后 - iloc按行号加载
代码实现:
# 取出data 的最后10行,此时a的索引列和行号不一致
a = data.tail(10)
print(a)
print()
# 获取索引列1694到1699的行
print(a.loc[1694:1700])
print()
# 获取行号为0,2,4的行
print(a.iloc[:5:2])
运行结果
3. 选择指定行和列
print(a.iloc[:5:2])
#%%
# 1. 获取指定 行|列 数据
data.loc[[0, 1, 2], ['country', 'year', 'lifeExp']] # 行索引, 列名
data.iloc[[0, 1, 2], [0, 2, 3]] # 行索引, 列的编号
# 2. 使用loc 获取所有行的, 某些列
data.loc[:, ['year', 'pop']] # 获取所有行的 year 和 pop列数据
# 3. 使用 iloc 获取所有行的, 某些列
data.iloc[:, [2, 3, -1]] # 获取所有行的, 索引为: 2, 3 以及 最后1列数据
# 4. loc只接收 行列名, iloc只接收行列序号, 搞反了, 会报错.
# df.loc[:, [2, 3, -1]] # 报错
# df.iloc[:, ['country', 'continent']] # 报错
# 5. 也可以通过 range()生成序号, 结合 iloc 获取连续多列数据.
data.iloc[:, range(1, 5, 2)]
data.iloc[:, list(range(1, 5, 2))] # 把range()转成列表, 再传入, 也可以.
# 6. 在iloc中, 使用切片语法 获取 n列数据.
data.iloc[:, 3:5] # 获取列编号为 3 ~ 5 区间的数据, 包左不包右, 即: 只获取索引为3, 4列的数据.
data.iloc[:, 0:6:2] # 获取列编号为 0 ~ 6 区间, 步长为2的数据, 即: 只获取索引为0, 2, 4列的数据.
# 7. 使用loc 和 iloc 获取指定行, 指定列的数据.
data.loc[42, 'country'] # 行索引为42, 列名为:country 的数据
data.iloc[42, 0] # 行号为42, 列编号为: 0 的数据
# 8. 获取多行多列
data.iloc[[0, 1, 2], [0, 2, 3]] # 行号, 列的编号
data.loc[2:6, ['country', 'lifeExp', 'gdpPercap']] # 行索引, 列名 推荐用法.
4. 布尔索引筛选
在Pandas中,布尔索引是一种非常强大的数据筛选方法,它允许你使用条件表达式来筛选DataFrame中的行。这种索引方式通过返回一个布尔序列(True/False)来工作,该序列与DataFrame的行相对应,然后只选择那些对应True的行。
# 创建一个简单的DataFrame
data1 = {'A': [1, 2, 3, 4, 5],
'B': [10, 20, 30, 40, 50],
'C': ['foo', 'bar', 'foo', 'bar', 'foo']}
df = pd.DataFrame(data1)
# 使用布尔索引筛选行
# 例如,筛选列'A'中值大于2的行
filtered_df = df[df['A'] > 2]
print(filtered_df)
# 也可以组合多个条件
# 例如,筛选列'A'中值大于2且列'C'中值为'foo'的行
combined_filtered_df = df[(df['A'] > 2) & (df['C'] == 'foo')]
print(combined_filtered_df)
运行结果:
在组合多个条件时,我们使用了Python的逻辑运算符&(与)和|(或)。在Pandas中,为了正确地对整个序列应用这些逻辑运算符,我们通常需要将它们放在括号内,以避免出现意外的行为。
布尔索引不仅限于单个列的条件,还可以基于多个列的组合条件,或者使用更复杂的表达式。它是DataFrame操作中非常灵活且强大的工具。
五、Dataframe 的常用方法
1. 数据统计与描述
(1). info()
用于快速获取 DataFrame 的简要摘要信息。输出以下信息:
- DataFrame 的范围(行数、列数)
- 每列的名称
- 每列的非空值数量
- 每列的数据类型
- 内存使用情况
运行结果:
(2). describe()
describe() 方法用于生成描述性统计信息,这些信息有助于我们快速了解DataFrame中数值型列的中心趋势、分散情况和分布形态。当你对一个包含数值数据的DataFrame调用 describe() 方法时,它会默认返回以下统计量:
- count:非空值的数量
- mean:平均值
- std:标准差
- min:最小值
- 25%:第一四分位数(即下四分位数,Q1)
- 50%:中位数(或第二四分位数,Q2)
- 75%:第三四分位数(即上四分位数,Q3)
- max:最大值
运行结果:
(3). mean() sum() min() max() var() std() quantile() cov()
- mean()
计算数值列的平均值。
df['column_name'].mean()
- sum()
计算数值列的总和。
df['column_name'].sum()
- min()
找出数值列的最小值。
df['column_name'].min()
- max()
找出数值列的最大值。
df['column_name'].max()
- var()
计算数值列的方差。
df['column_name'].var()
- std()
计算数值列的标准差。
df['column_name'].std()
- quantile() 或 quantile(q)
计算数值列的分位数(quantile)。参数 q 是一个介于0和1之间的数字或序列,代表所需分位数的位置。例如,quantile(0.5) 会返回中位数。
df['column_name'].quantile(0.5) # 中位数
- cov()
计算两个数值列之间的协方差。
df['column1'].cov(df['column2'])
这些方法在数据分析中非常有用,因为它们提供了关于数据分布和变量之间关系的快速概览。需要注意的是,这些方法默认应用于数值型数据。如果尝试对非数值型数据(如字符串或日期)使用这些方法,通常会引发错误。
此外,DataFrame 对象上的 describe() 方法通常结合了上述方法中的一些(例如 mean(), std(), min(), max()),以提供一个关于所有数值列的统计摘要。
在使用这些方法时,确保您的数据没有缺失值(NaN),或者您已经以某种方式处理了这些缺失值,因为它们的存在可能会影响统计结果。如果需要处理缺失值,可以使用 dropna() 方法删除包含缺失值的行,或者使用 fillna() 方法填充缺失值。
六、Dataframe 修改行列索引
1. 创建时用index_col 指定索引
在创建Dataframe的时候即可用index_col指定索引
4. set_index()和reset_index()
- set_index()设置行索引
- reset_index() 重置列索引
代码实现:
# 取data的前3列
a = data.iloc[:5,:3]
print(a)
print()
# 设置行索引为color列
a.set_index('color',inplace = True)
print(a)
print()
# 重置行索引
a.reset_index(inplace = True)
print(a)
运行结果:
3. rename()函数修改
格式: rename(index = {‘原索引值1’:新索引值1,‘原索引值2‘:新索引值2,},columns={'原列名1‘:新列名1},…)
代码实现:
4. 添加 删除 插入列
- 添加 和 插入
Dataframe[新列名] = 值 在末尾添加一列
insert(loc = n , column = ‘新列名’,value = 值)指定位置插入列,n为插入的列索引
代码实现:
a = data.iloc[:5,:4]
print(a)
print()
# 直接添加列
a['c'] = 1
print(a)
print()
# insert添加
a.insert(loc= 1,column='bb',value = 1)
print(a)
运行结果:
- 删除
drop(labols,axis= 1/0,inplace= True/Flalse)- labols: 行标签或列标签
- axis: 0/index 为行,1/columns 为列
- inplace: 默认为False 不在Dataframe上修改,True为在原Dataframe上修改
代码实现:
print(a)
print()
# 删除color列
a.drop('color',axis= 1,inplace= True)
print(a)
运行结果:
七、下期内容
1.Dataframe 数据的清洗和预处理
排序
去重
缺失值处理
分组聚合
数据的重塑与转换
2. 多个Dataframe的操作
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)