DataFrame常用方法(下)

上期我们介绍完了notnull()方法,本期继续介绍剩下的方法:

方法 简要描述
head(n) 展示 DataFrame 的前 n 行数据。
tail(n) 展示 DataFrame 的最后 n 行数据。
info() 提供 DataFrame 的基本信息概览。
describe() 生成数值列的统计摘要。
shape 返回 DataFrame 的尺寸。
columns 列出所有的列名。
index 显示行标签的索引。
dtypes 获取各列的数据类型。
sort_values(by) 根据指定列对 DataFrame 进行排序。
sort_index() 按照行索引排序 DataFrame。
dropna() 移除包含缺失值的行或列。
fillna(value) 用特定值填充缺失值。
isnull() 检测 DataFrame 中的缺失值。
notnull() 检测 DataFrame 中的非缺失值。
loc[] 通过标签选取数据。
iloc[] 通过位置选取数据。
at[] 高效访问单个元素,基于标签。
iat[] 高效访问单个元素,基于整数位置。
apply(func) 将函数应用于 DataFrame 或 Series。
applymap(func) 将函数映射到 DataFrame 的每个元素。
groupby(by) 根据一个或多个列对数据进行分组。
pivot_table() 构建数据透视表。
merge() 结合两个 DataFrame。
concat() 连接多个 DataFrame 对象。
to_csv() 保存 DataFrame 到 CSV 文件。
to_excel() 保存 DataFrame 到 Excel 文件。
to_json() 将 DataFrame 转换为 JSON 格式。
to_sql() 将 DataFrame 写入 SQL 数据库。
query() 用类似 SQL 的表达式查询 DataFrame。
duplicated() 标识重复的行。
drop_duplicates() 删除重复的行。
set_index() 设定新的索引列。
reset_index() 重置索引为默认整数索引。
transpose() 交换 DataFrame 的行和列。

函数目录

loc[] 属性

loc[ ] 是 Pandas 库中 DataFrame 和 Series 对象的一个属性,用于通过标签(行和列名)来访问数据。它提供了一种基于标签的索引方式,允许用户以直观的方式选择数据子集、获取单个值或进行更复杂的选择操作。

特点:

  • 标签索引:使用 loc[] 时,必须提供确切的行和/或列标签,不能使用整数位置。
  • 包含性边界:当使用切片语法时,loc[] 包含上界和下界的标签。
  • 布尔索引:可以结合布尔数组进行条件选择。

语法:

DataFrame.loc[row_indexer, column_indexer]

使用示例:

<!-- Python code using Pandas -->
import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'A': [1, 2, 3],
    'B': ['a', 'b', 'c'],
    'C': [True, False, True]
}
df = pd.DataFrame(data, index=['x', 'y', 'z'])

print("原始 DataFrame:")
print(df)

# 选择单个元素
single_element = df.loc['x', 'A']

print("\n选择单个元素 (位于 'x' 行 'A' 列):")
print(single_element)

# 选择多行和多列
multiple_rows_columns = df.loc[['x', 'z'], ['A', 'C']]

print("\n选择多行 ('x', 'z') 和多列 ('A', 'C'):")
print(multiple_rows_columns)

# 使用切片选择行
sliced_rows = df.loc['x':'y']

print("\n使用切片选择行 ('x' 到 'y'):")
print(sliced_rows)

# 布尔索引选择
boolean_selection = df.loc[df['C'] == True]

print("\n布尔索引选择 (列 'C' 为 True 的行):")
print(boolean_selection)

iloc[] 属性

iloc[] 是 Pandas 库中 DataFrame 和 Series 对象的一个属性,用于通过整数位置(基于位置的索引)来访问数据。与 loc[] 不同,iloc[] 依赖于行和列的位置编号,而不是标签,这使得它非常适合进行基于位置的数据选择和操作。

特点:

  • 位置索引:使用 iloc[] 时,必须提供确切的行和/或列的位置编号,而不是标签。
  • 不包含上界:当使用切片语法时,iloc[] 的切片行为类似于 Python 列表切片,即不包含上界。
  • 支持布尔索引:可以结合布尔数组进行条件选择。

语法:

DataFrame.iloc[row_indexer, column_indexer]

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'A': [1, 2, 3],
    'B': ['a', 'b', 'c'],
    'C': [True, False, True]
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 选择单个元素 (位于第 0 行第 0 列)
single_element = df.iloc[0, 0]

print("\n选择单个元素 (位于第 0 行第 0 列):")
print(single_element)

# 选择多行和多列 (第 0 行和第 2 行,以及第 0 列和第 2 列)
multiple_rows_columns = df.iloc[[0, 2], [0, 2]]

print("\n选择多行 (第 0 行和第 2 行) 和多列 (第 0 列和第 2 列):")
print(multiple_rows_columns)

# 使用切片选择行 (从第 0 行到第 1 行,不包括第 2 行)
sliced_rows = df.iloc[0:2]

print("\n使用切片选择行 (从第 0 行到第 1 行):")
print(sliced_rows)

# 布尔索引选择 (选择所有行,但只选择前两列)
boolean_selection = df.iloc[:, :2]

print("\n布尔索引选择 (选择所有行,但只选择前两列):")
print(boolean_selection)

at[] 属性

at[] 是 Pandas 库中 DataFrame 对象的一个属性,专门用于快速访问标量值(单个元素),通过行标签和列标签进行索引。与 loc[] 不同,at[] 仅适用于获取或设置单一值,而不是选择多个元素或子集。因此,它提供了更高效的方式来访问特定位置的数据。

特点:

  • 标签索引:使用 at[] 时,必须提供确切的行标签和列标签。
  • 效率高:由于是针对单个元素的操作,所以比 loc[] 更快。
  • 只读取或修改单个值:不支持选择多行或多列。

语法:

DataFrame.at[row_label, column_label]

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'A': [1, 2, 3],
    'B': ['a', 'b', 'c'],
    'C': [True, False, True]
}
df = pd.DataFrame(data, index=['x', 'y', 'z'])

print("原始 DataFrame:")
print(df)

# 获取单个元素 (位于 'x' 行 'A' 列)
single_element = df.at['x', 'A']

print("\n获取单个元素 (位于 'x' 行 'A' 列):")
print(single_element)

# 修改单个元素 (将 'y' 行 'B' 列的值改为 'd')
df.at['y', 'B'] = 'd'

print("\n修改后的 DataFrame:")
print(df)

上述代码展示了如何使用 at[] 属性来获取和修改 DataFrame 中的单个元素。你可以根据需要指定确切的行和列标签来访问或更改数据。

注意事项:

  • 只适用于单个值:at[] 不能用于选择多个元素或执行切片操作。如果你需要选择多个元素,请使用 loc[] 或其他适当的方法。
  • 确保标签存在:在使用 at[] 访问数据之前,确保提供的行和列标签确实存在于 DataFrame 中,以避免引发 KeyError。

iat[] 属性

iat[] 是 Pandas 库中 DataFrame 对象的一个属性,专门用于快速访问标量值(单个元素),通过整数位置进行索引。与 iloc[] 不同,iat[] 仅适用于获取或设置单一值,而不是选择多个元素或子集。因此,它提供了更高效的方式来访问特定位置的数据。

特点:

  • 整数位置索引:使用 iat[] 时,必须提供确切的行和列的整数位置。
  • 效率高:由于是针对单个元素的操作,所以比 iloc[] 更快。
  • 只读取或修改单个值:不支持选择多行或多列。

语法:

DataFrame.iat[row_position, column_position]

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'A': [1, 2, 3],
    'B': ['a', 'b', 'c'],
    'C': [True, False, True]
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 获取单个元素 (位于第 0 行第 0 列)
single_element = df.iat[0, 0]

print("\n获取单个元素 (位于第 0 行第 0 列):")
print(single_element)

# 修改单个元素 (将第 1 行第 1 列的值改为 'd')
df.iat[1, 1] = 'd'

print("\n修改后的 DataFrame:")
print(df)

上述代码展示了如何使用 iat[] 属性来获取和修改 DataFrame 中的单个元素。你可以根据需要指定确切的行和列的位置编号来访问或更改数据。

注意事项:

  • 只适用于单个值:iat[] 不能用于选择多个元素或执行切片操作。如果你需要选择多个元素,请使用 iloc[] 或其他适当的方法。
  • 确保位置有效:在使用 iat[] 访问数据之前,确保提供的行和列的位置编号在有效的范围内,以避免引发 IndexError。

总结来说,当你明确知道要访问或修改的是哪个具体位置的元素,并且想要获得最快的操作速度时,应该优先考虑使用 iat[]。这可以显著提升性能,尤其是在处理大型数据集时。

loc[], iloc[], at[], iat[] 对比

Pandas 提供了四种主要的索引方式:loc[], iloc[], at[], 和 iat[],每种方式都有其特定的应用场景和特点。理解它们之间的差异有助于更高效地操作 DataFrame 或 Series 数据。

属性 loc[] iloc[] at[] iat[]
标签/位置索引 通过行和列的标签来访问数据。 通过行和列的位置编号(整数)来访问数据。 专门用于快速访问标量值(单个元素),通过行标签和列标签进行索引。 专门用于快速访问标量值(单个元素),通过行和列的位置编号(整数)进行索引。
切片行为 包含上界和下界的标签。 不包含上界的整数位置。
布尔索引 支持结合布尔数组进行条件选择。 支持结合布尔数组进行条件选择。
适用场景 当需要基于标签进行灵活的数据选择时使用。 当需要基于位置进行数据选择时使用,特别是对于没有明确标签或想要避免标签带来的混淆时。 当需要高效访问或修改单个元素时使用。 当需要高效访问或修改单个元素时使用,特别是在按位置索引的情况下。
效率高 由于是针对单个元素的操作,所以比 loc[] 更快。 由于是针对单个元素的操作,所以比 iloc[] 更快。
只读取或修改单个值 不支持选择多行或多列。 不支持选择多行或多列。

以下是使用示例对比:

loc[] 示例

# 选择所有行中 'A' 列的数据
print(df.loc[:, 'A'])

iloc[] 示例

# 选择第 0 行到第 1 行的所有列的数据
print(df.iloc[0:2, :])

at[] 示例

# 获取位于 'x' 行 'A' 列的单个元素
print(df.at['x', 'A'])

# 修改位于 'y' 行 'B' 列的单个元素为 'd'
df.at['y', 'B'] = 'd'

iat[] 示例

# 获取位于第 0 行第 0 列的单个元素
print(df.iat[0, 0])

# 修改位于第 1 行第 1 列的单个元素为 'd'
df.iat[1, 1] = 'd'

apply(func) 方法

apply() 是 Pandas 库中 DataFrame 和 Series 对象的一个方法,用于将一个函数应用到 DataFrame 的行或列,或者应用到 Series 的元素上。它是一个非常灵活的方法,可以用来执行各种数据转换和聚合操作。

特点:

  • 灵活性:可以应用于整个 DataFrame、单个 Series 或者 DataFrame 的每一行或每一列。
  • 自定义函数支持:接受任何用户定义的函数作为参数,并将其应用到指定的数据结构上。
  • 聚合与转换:既可以用于数据的转换(例如字符串操作、数学运算),也可以用于聚合操作(例如统计计算)。

语法:

DataFrame.apply(func, axis=0, raw=False, result_type=None, args=(), **kwds)

参数:

  • func: 函数、字典或可调用对象。要应用的函数。
  • axis: {0 或 ‘index’, 1 或 ‘columns’},默认为 0。轴向选择:0 表示按列应用函数(默认),1 表示按行应用函数。
  • raw: 布尔值,默认为 False。如果为 True,则以 NumPy 数组的形式传递数据;如果为 False,则以 Series 形式传递。
  • result_type: {‘expand’, ‘reduce’, ‘broadcast’}, 可选。控制返回结果的类型:
    • ‘expand’:列表-like 结果会变成列。
    • ‘reduce’:总是返回 Series。
    • ‘broadcast’:结果会广播回输入的形状。
  • args: 元组,默认为空。传递给函数的额外位置参数。
  • **kwds: 传递给函数的额外关键字参数。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'A': [1, 2, 3],
    'B': ['a', 'b', 'c'],
    'C': [True, False, True]
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 使用 apply() 对每列求和
column_sum = df[['A']].apply(sum)

print("\n对每列求和的结果 (仅数值列):")
print(column_sum)

# 使用 apply() 对每行进行自定义操作
def custom_operation(row):
    return f"{row['A']}-{row['B']}"

row_custom_op = df.apply(custom_operation, axis=1)

print("\n对每行进行自定义操作的结果:")
print(row_custom_op)

# 使用 apply() 结合 lambda 函数对 Series 进行操作
series_lambda_op = df['B'].apply(lambda x: x.upper())

print("\n使用 lambda 函数对 Series 进行大写转换的结果:")
print(series_lambda_op)

上述代码展示了如何使用 apply() 方法来对 DataFrame 和 Series 进行不同类型的函数应用。你可以根据需要选择应用函数的对象(行或列)、传递额外的参数,并结合其他 Pandas 功能实现复杂的数据处理逻辑。

注意事项:

  • 对于大型数据集,apply() 可能不是最高效的选项,因为它不利用底层的优化循环。在这种情况下,考虑使用更高效的方法如 vectorized operations 或者内置的 Pandas/NumPy 函数。
  • 确保传递给 apply() 的函数能够正确处理传入的数据类型,特别是在使用 raw=True 时。

关于apply (func) 方法妙用还有很多,灵活运用apply (func) 方法可以省下很多直接对df进行遍历的操作,尤其是针对大型数据集操作,我开一个文章会专门讲解apply的应用。

applymap(func) 方法

applymap() 是 Pandas 库中 DataFrame 对象的一个方法,专门用于将一个函数应用到 DataFrame 的每一个元素上。与 apply() 不同的是,applymap() 不能直接应用于行或列,而是针对每个单独的元素进行操作。它非常适合用于对整个 DataFrame 进行逐元素的数据转换。

特点:

  • 逐元素应用:可以将函数应用到 DataFrame 中的每一个标量值。
  • 简单数据类型转换:适用于简单的数据类型转换或数学运算。
  • 自定义函数支持:接受任何用户定义的函数作为参数,并将其应用到 DataFrame 的每个元素上。

语法:

DataFrame.applymap(func)

参数:

  • func: 函数或可调用对象。要应用到 DataFrame 每个元素上的函数。该函数应接受一个标量输入并返回一个标量输出。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'A': [1, 2, 3],
    'B': ['a', 'b', 'c'],
    'C': [True, False, True]
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 使用 applymap() 对所有数值元素进行平方操作
def square(x):
    if isinstance(x, (int, float)):
        return x ** 2
    return x

df_squared = df.applymap(square)

print("\n对所有数值元素进行平方后的 DataFrame:")
print(df_squared)

# 使用 applymap() 结合 lambda 函数对字符串元素进行大写转换
df_uppercase = df.applymap(lambda x: x.upper() if isinstance(x, str) else x)

print("\n使用 lambda 函数对字符串元素进行大写转换后的 DataFrame:")
print(df_uppercase)

# 使用 applymap() 对布尔值进行反转
df_bool_inverted = df.applymap(lambda x: not x if isinstance(x, bool) else x)

print("\n对布尔值进行反转后的 DataFrame:")
print(df_bool_inverted)

上述代码展示了如何使用 applymap() 方法来对 DataFrame 的每一个元素应用不同的函数。你可以根据需要选择应用特定类型的转换逻辑,比如数值计算、字符串处理或布尔操作。

注意事项:

  • 只适用于 DataFrame:applymap() 只能用于 DataFrame,不能用于 Series。对于 Series,应该使用 apply() 方法。
  • 性能考虑:对于大型 DataFrame,applymap() 可能不是最高效的选项,因为它不利用底层的优化循环。在这种情况下,考虑使用更高效的方法如 vectorized operations 或者内置的 Pandas/NumPy 函数。
  • 确保函数兼容性:传递给 applymap() 的函数必须能够正确处理传入的每种数据类型,并且应该为每个元素返回一个单一的标量值。

groupby(by) 方法

groupby() 是 Pandas 库中 DataFrame 和 Series 对象的一个方法,用于根据一个或多个键(列)对数据进行分组。它允许用户基于某些标准将数据分割成不同的组,并对每个组执行聚合、转换或其他操作。这是数据分析中非常重要的一步,因为它可以帮助我们理解数据的内部结构和模式。

特点:

  • 灵活分组:可以根据单个或多个列进行分组。
  • 支持多种操作:可以应用于分组后的数据上执行聚合、转换、过滤等操作。
  • 处理复杂数据:适用于各种类型的数据,包括数值、类别和其他自定义类型。

语法:

DataFrame.groupby(by=None, axis=0, level=None, as_index=True, sort=True, group_keys=True, squeeze=False, observed=False, dropna=True)

参数:

  • by: 标量、列表或数组、字典、Series 或函数。用于分组的键或键的组合。它可以是列名、列的列表、映射到列的字典、或者是一个计算组键的函数。
  • axis: {0 或 ‘index’, 1 或 ‘columns’},默认为 0。轴向选择:0 表示按行分组(默认),1 表示按列分组。
  • level: 整数、字符串或整数/字符串列表。如果索引有多级(MultiIndex),则指定用哪一级作为分组键。
  • as_index: 布尔值,默认为 True。如果为 True,则分组结果中分组的键会成为索引;如果为 False,则它们会被添加为新列。
  • sort: 布尔值,默认为 True。是否对分组键进行排序。
  • group_keys: 布尔值,默认为 True。是否在结果中包含分组键。
  • squeeze: 布尔值,默认为 False。如果分组后只有一列,是否将结果压缩为 Series。
  • observed: 布尔值,默认为 False。对于分类数据,是否排除未观察到的类别。
  • dropna: 布尔值,默认为 True。是否从结果中移除包含缺失值的组。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'Category': ['A', 'B', 'A', 'B', 'C'],
    'Value': [10, 20, 30, 40, 50],
    'Weight': [1.1, 2.2, 3.3, 4.4, 5.5]
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 使用 groupby() 按 'Category' 列分组并求和
grouped_sum = df.groupby('Category')['Value'].sum()

print("\n按 'Category' 分组并对 'Value' 求和的结果:")
print(grouped_sum)

# 使用 groupby() 按 'Category' 列分组并计算平均值
grouped_mean = df.groupby('Category').mean()

print("\n按 'Category' 分组并计算所有数值列的平均值的结果:")
print(grouped_mean)

# 使用 groupby() 和多个键进行分组
multi_grouped = df.groupby(['Category', 'Weight']).sum()

print("\n按 'Category' 和 'Weight' 多个键分组并对 'Value' 求和的结果:")
print(multi_grouped)

# 使用 groupby() 并应用自定义聚合函数
custom_agg = df.groupby('Category').agg({'Value': 'sum', 'Weight': 'mean'})

print("\n按 'Category' 分组并应用自定义聚合函数的结果:")
print(custom_agg)

上述代码展示了如何使用 groupby() 方法来对 DataFrame 进行不同类型的分组操作。你可以根据需要选择分组键、指定要应用的操作,并结合其他 Pandas 功能实现复杂的数据分析逻辑。

注意事项:

  • 性能优化:对于大型数据集,确保使用的分组键确实能够有效地减少数据量,以避免潜在的性能问题。
  • 正确设置参数:根据具体需求调整 groupby() 的参数,例如 as_index, sort 等,以获得预期的结果格式。
  • 考虑内存限制:分组操作可能会创建大量的中间数据结构,因此要注意内存使用情况,特别是在处理大规模数据时。

pivot_table() 方法

pivot_table() 是 Pandas 库中 DataFrame 对象的一个方法,用于创建数据透视表(Pivot Table),这是数据分析中一种强大的工具。它允许用户根据一个或多个键对数据进行分组,并计算这些组的汇总统计信息。数据透视表可以用来分析、汇总和展示复杂的数据集,使得数据模式和关系更加清晰。

特点:

  • 灵活的分组与聚合:可以根据多个列进行分组,并应用多种聚合函数。
  • 多维数据分析:支持按行和列进行分组,以及添加多个值列来同时查看不同的聚合结果。
  • 内置边缘总计:可以自动计算并显示每行、每列以及整个表格的汇总统计。

语法:

DataFrame.pivot_table(values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All', observed=False)

参数:

  • values: 字符串或字符串列表。要聚合的数据列名。
  • index: 标量、列表或数组。作为行标签的列名或列名列表。
  • columns: 标量、列表或数组。作为列标签的列名或列名列表。
  • aggfunc: 函数、字符串、列表或字典,默认为 ‘mean’。用于聚合的函数或函数列表。常见的聚合函数包括 sum, mean, count, min, max 等。也可以是自定义函数。
  • fill_value: 标量值,默认为 None。用以替换缺失值。
  • margins: 布尔值,默认为 False。是否添加边缘总计行和列。
  • dropna: 布尔值,默认为 True。是否从结果中移除包含缺失值的行或列。
  • margins_name: 字符串,默认为 ‘All’。边缘总计行和列的名称。
  • observed: 布尔值,默认为 False。对于分类数据,是否排除未观察到的类别。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'Category': ['A', 'B', 'A', 'B', 'C'],
    'Subcategory': ['X', 'Y', 'X', 'Y', 'Z'],
    'Value': [10, 20, 30, 40, 50]
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 使用 pivot_table() 创建数据透视表,按 'Category' 分组并对 'Value' 求和
pivot_sum = df.pivot_table(values='Value', index='Category', aggfunc='sum')

print("\n按 'Category' 分组并对 'Value' 求和的结果:")
print(pivot_sum)

# 使用 pivot_table() 创建数据透视表,按 'Category' 和 'Subcategory' 分组并对 'Value' 计算均值
pivot_mean = df.pivot_table(values='Value', index='Category', columns='Subcategory', aggfunc='mean')

print("\n按 'Category' 和 'Subcategory' 分组并对 'Value' 计算均值的结果:")
print(pivot_mean)

# 使用 pivot_table() 并添加边缘总计
pivot_with_margins = df.pivot_table(values='Value', index='Category', columns='Subcategory', aggfunc='sum', margins=True)

print("\n按 'Category' 和 'Subcategory' 分组并对 'Value' 求和,同时添加边缘总计的结果:")
print(pivot_with_margins)

上述代码展示了如何使用 pivot_table() 方法来创建不同类型的透视表。你可以根据需要选择分组键、指定要聚合的列以及应用的聚合函数,并结合其他 Pandas 功能实现复杂的数据分析逻辑。

注意事项:

  • 性能优化:对于大型数据集,确保使用的分组键能够有效地减少数据量,以避免潜在的性能问题。
  • 正确设置参数:根据具体需求调整 pivot_table() 的参数,例如 aggfunc, margins 等,以获得预期的结果格式。
  • 考虑内存限制:创建透视表可能会生成大量的中间数据结构,因此要注意内存使用情况,特别是在处理大规模数据时。

merge() 方法

merge() 是 Pandas 库中的一个方法,用于根据一个或多个键将两个 DataFrame 对象连接在一起。它类似于 SQL 中的 JOIN 操作,提供了多种方式来合并数据集,包括一对一、一对多或多对多的关系。此方法对于整合来自不同来源的数据非常有用,可以用来创建更全面的数据视图。

特点:

  • 多样化的连接方式:支持内连接(inner join)、左连接(left join)、右连接(right join)和外连接(outer join)。
  • 灵活的键选择:可以根据单个或多个键进行匹配,确保准确地组合相关数据。
  • 处理重叠列名:能够自动处理或指定如何解决左右 DataFrame 中存在的同名列。

语法:

pandas.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)

参数:

  • left: DataFrame。左侧的 DataFrame。
  • right: DataFrame。右侧的 DataFrame。
  • how: {‘left’, ‘right’, ‘outer’, ‘inner’}, 默认为 ‘inner’。合并类型:
    • ‘left’: 使用左 DataFrame 的键作为结果的键;保留左 DataFrame 的所有记录,缺失值填充 NaN。
    • ‘right’: 使用右 DataFrame 的键作为结果的键;保留右 DataFrame 的所有记录,缺失值填充 NaN。
    • ‘outer’: 使用左右 DataFrame 键的并集;任何一侧没有匹配的记录都将填充 NaN。
    • ‘inner’: 使用左右 DataFrame 键的交集;只保留有匹配的记录。
  • on: 字符串或字符串列表。在两个 DataFrame 上都存在的列名,用于连接。如果未提供,则会尝试使用 left_onright_on 参数。
  • left_on: 标量、列表或数组。仅在左侧 DataFrame 上的列名或键,用于连接。
  • right_on: 标量、列表或数组。仅在右侧 DataFrame 上的列名或键,用于连接。
  • left_index: 布尔值,默认为 False。是否使用左侧 DataFrame 的索引作为连接键。
  • right_index: 布尔值,默认为 False。是否使用右侧 DataFrame 的索引作为连接键。
  • sort: 布尔值,默认为 False。是否对合并后的结果按照连接键排序。
  • suffixes: 2 元组,默认为 (‘_x’, ‘_y’)。当存在重复列名时,给左右 DataFrame 添加的后缀。
  • copy: 布尔值,默认为 True。是否复制数据,即使不需要。
  • indicator: 布尔值或字符串,默认为 False。如果为 True 或者是一个字符串,则添加一列指示每行来自哪个 DataFrame。
  • validate: {‘one_to_one’, ‘one_to_many’, ‘many_to_one’, ‘many_to_many’},默认为 None。检查连接键之间的关系,并在不符合预期时引发异常。

使用示例:

import pandas as pd

# 创建两个简单的 DataFrame
left_df = pd.DataFrame({
    'key': ['A', 'B', 'C', 'D'],
    'value_left': [1, 2, 3, 4]
})

right_df = pd.DataFrame({
    'key': ['B', 'D', 'E', 'F'],
    'value_right': [5, 6, 7, 8]
})

print("左侧 DataFrame:")
print(left_df)

print("\n右侧 DataFrame:")
print(right_df)

# 使用 merge() 执行内连接
merged_inner = pd.merge(left_df, right_df, on='key')

print("\n执行内连接的结果:")
print(merged_inner)

# 使用 merge() 执行左连接
merged_left = pd.merge(left_df, right_df, how='left', on='key')

print("\n执行左连接的结果:")
print(merged_left)

# 使用 merge() 并指定不同的键进行连接
merged_diff_keys = pd.merge(left_df, right_df, left_on='key', right_on='key', suffixes=('_l', '_r'))

print("\n指定不同键进行连接的结果:")
print(merged_diff_keys)

# 使用 merge() 并添加合并指示器
merged_with_indicator = pd.merge(left_df, right_df, on='key', indicator=True)

print("\n添加合并指示器的结果:")
print(merged_with_indicator)

上述代码展示了如何使用 merge() 方法来根据不同的键和连接方式进行 DataFrame 的合并操作。你可以根据需要选择适当的连接类型、指定要使用的键,并结合其他 Pandas 功能实现复杂的数据整合逻辑。

注意事项:

  • 性能优化:对于大型数据集,确保使用的连接键是索引或已排序的,以提高合并效率。
  • 正确设置参数:根据具体需求调整 merge() 的参数,例如 how, on, suffixes 等,以获得预期的结果格式。
  • 考虑内存限制:合并操作可能会生成大量的中间数据结构,因此要注意内存使用情况,特别是在处理大规模数据时。

concat() 方法

concat() 是 Pandas 库中的一个方法,用于沿指定轴(行或列)连接多个 DataFrame 或 Series 对象。它提供了灵活的方式将不同数据集组合在一起,而不需要它们之间有明确的键或索引对应关系。这使得 concat() 成为合并、追加和堆叠数据集的强大工具。

特点:

  • 多对象支持:可以同时连接多个 DataFrame 或 Series。
  • 轴向选择:可以选择沿着行(axis=0,默认)或列(axis=1)进行连接。
  • 索引处理:能够保留原始索引或创建新的默认索引。
  • 灵活性:适用于不同的连接场景,如垂直堆叠、水平拼接等。

语法:

pandas.concat(objs, axis=0, join='outer', ignore_index=False, keys=None, levels=None, names=None, verify_integrity=False, copy=True)

参数:

  • objs: DataFrame 或 Series 的序列(列表、元组等)。要连接的对象集合。
  • axis: {0 或 ‘index’, 1 或 ‘columns’},默认为 0。轴向选择:0 表示沿行连接(默认),1 表示沿列连接。
  • join: {‘inner’, ‘outer’},默认为 ‘outer’。指定如何处理非共有的索引:
    • ‘inner’: 只保留所有输入对象中共有的索引标签。
    • ‘outer’: 保留所有输入对象中出现的所有索引标签,并用 NaN 填充缺失值。
  • ignore_index: 布尔值,默认为 False。如果为 True,则不使用原始索引,而是生成一个新的整数范围索引。
  • keys: 序列,默认为 None。如果提供,会为每个输入对象的结果添加一层额外的 MultiIndex 级别。
  • levels: 序列列表,默认为 None。与 keys 参数一起使用,用于定义 keys 中每个级别的唯一标识符。
  • names: 字符串或字符串列表,默认为 None。MultiIndex 级别的名称。
  • verify_integrity: 布尔值,默认为 False。是否检查新索引是否有重复值。
  • copy: 布尔值,默认为 True。是否复制数据,即使不需要。

使用示例:

import pandas as pd

# 创建两个简单的 DataFrame
df1 = pd.DataFrame({
    'A': ['A0', 'A1', 'A2'],
    'B': ['B0', 'B1', 'B2']
})

df2 = pd.DataFrame({
    'A': ['A3', 'A4', 'A5'],
    'B': ['B3', 'B4', 'B5']
})

print("第一个 DataFrame:")
print(df1)

print("\n第二个 DataFrame:")
print(df2)

# 使用 concat() 沿行连接两个 DataFrame
concatenated_rows = pd.concat([df1, df2])

print("\n沿行连接后的结果:")
print(concatenated_rows)

# 使用 concat() 沿列连接两个 DataFrame
concatenated_columns = pd.concat([df1, df2], axis=1)

print("\n沿列连接后的结果:")
print(concatenated_columns)

# 使用 concat() 并忽略原始索引
concatenated_ignore_index = pd.concat([df1, df2], ignore_index=True)

print("\n忽略原始索引后连接的结果:")
print(concatenated_ignore_index)

# 使用 concat() 添加 MultiIndex 级别
concatenated_with_keys = pd.concat([df1, df2], keys=['x', 'y'])

print("\n添加 MultiIndex 级别后连接的结果:")
print(concatenated_with_keys)

上述代码展示了如何使用 concat() 方法来根据不同的轴和选项连接多个 DataFrame。你可以根据需要选择适当的连接方式、指定要使用的轴以及调整其他参数,以实现复杂的数据组合逻辑。

注意事项:

  • 性能优化:对于大型数据集,确保连接操作不会导致不必要的内存占用或计算开销。尽可能避免频繁地对大表进行连接操作。
  • 正确设置参数:根据具体需求调整 concat() 的参数,例如 axis, join, ignore_index 等,以获得预期的结果格式。
  • 考虑数据一致性:在连接之前检查数据的一致性,特别是当使用 join='inner'join='outer' 时,确保理解哪些数据会被保留或丢弃。

to_csv() 方法

to_csv() 是 Pandas 库中 DataFrame 和 Series 对象的一个方法,用于将数据导出到 CSV(逗号分隔值)文件。CSV 文件是一种常见的文本文件格式,用于存储表格数据,非常适合与不同软件和平台之间交换数据。此方法提供了多种参数选项来定制输出文件的格式和内容。

特点:

  • 灵活的数据导出:可以轻松地将 DataFrame 或 Series 的数据保存为 CSV 文件。
  • 多种格式选项:支持自定义分隔符、列名、索引等输出设置。
  • 广泛兼容性:生成的 CSV 文件可以被大多数电子表格程序和数据分析工具读取。

语法:

DataFrame.to_csv(path_or_buf=None, sep=',', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, mode='w', encoding=None, compression='infer', quoting=None, quotechar='"', line_terminator=None, chunksize=None, date_format=None, doublequote=True, escapechar=None, decimal='.')

参数:

  • path_or_buf: 字符串或文件句柄,默认为 None。如果为字符串,则表示要写入的文件路径;如果为文件句柄,则直接写入该对象。如果为 None,则返回一个字符串。
  • sep: 字符,默认为 ‘,’。字段之间的分隔符。
  • na_rep: 字符串,默认为空字符串 ”。用于表示缺失值的字符串。
  • float_format: 字符串,默认为 None。浮点数的格式化字符串。
  • columns: 列表,默认为 None。要导出的列名列表。
  • header: 布尔值或列表,默认为 True。是否包含列名作为文件头。如果是列表,则使用提供的列名。
  • index: 布尔值,默认为 True。是否将索引写入文件。
  • index_label: 字符串或序列,默认为 None。索引列的标签。
  • mode: {‘w’, ‘a’},默认为 ‘w’。文件打开模式:’w’ 表示覆盖写入,’a’ 表示追加写入。
  • encoding: 字符串,默认为 None。文件编码格式,例如 ‘utf-8’。
  • compression: {‘infer’, ‘gzip’, ‘bz2’, ‘zip’, ‘xz’, None},默认为 ‘infer’。压缩类型。
  • quoting: 整数或 csv.QUOTE_* 常量,默认为 None。控制何时引用字段。
  • quotechar: 字符,默认为 ‘”‘。用于包围字段的字符。
  • line_terminator: 字符串,默认为 None。行尾终止符。
  • chunksize: 整数,默认为 None。每次写入的行数。
  • date_format: 字符串,默认为 None。日期时间格式。
  • doublequote: 布尔值,默认为 True。是否用两个引号表示引号。
  • escapechar: 字符,默认为 None。转义字符。
  • decimal: 字符,默认为 ‘.’。小数点符号。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [25, 30, 35],
    'City': ['New York', 'Los Angeles', 'Chicago']
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 使用 to_csv() 将 DataFrame 导出为 CSV 文件
df.to_csv('output.csv', index=False)  # 不导出索引

# 使用 to_csv() 并指定分隔符和其他选项
df.to_csv('output_semicolon.csv', sep=';', index=False, header=True)

# 使用 to_csv() 导出特定列并处理缺失值
df_with_na = df.copy()
df_with_na.loc[1, 'City'] = None  # 添加一个缺失值
df_with_na.to_csv('output_with_na.csv', na_rep='N/A', index=False)

# 使用 to_csv() 追加写入现有文件
df_with_na.to_csv('output_append.csv', mode='a', header=False, index=False)

上述代码展示了如何使用 to_csv() 方法根据不同的需求将 DataFrame 导出为 CSV 文件。你可以选择是否导出索引、指定分隔符、处理缺失值以及调整其他输出设置,以确保生成的文件符合预期。

注意事项:

  • 文件路径:确保提供的文件路径是有效的,并且有适当的权限进行写入操作。
  • 编码问题:根据目标系统的需要选择正确的文件编码,避免出现乱码问题。
  • 性能考虑:对于大型 DataFrame,考虑使用 chunksize 参数分批次导出数据,以减少内存占用。
  • 数据一致性:在导出之前检查数据的一致性和完整性,特别是当涉及到日期格式、缺失值处理等。

倒出时间的问题上,如果想要导出的数据用Excel直接打开,将数据导出到csv时间是最快的,尤其是数十万行的数据,不过要注意,Excel最多能处理104万行的数据,而且数据多了以后,Excel基本上是无法处理的。

to_excel() 方法

to_excel() 是 Pandas 库中 DataFrame 和 Series 对象的一个方法,用于将数据导出到 Excel 文件。Excel 是一种广泛使用的电子表格软件,支持多种数据格式和丰富的功能,非常适合用于数据分析、可视化和报告生成。通过 to_excel() 方法,可以轻松地将 Pandas 的数据结构保存为 Excel 文件,以便与他人共享或进一步处理。

特点:

  • 多表支持:可以在同一个 Excel 文件中创建多个工作表。
  • 样式和格式:虽然直接的样式设置有限,但可以通过 ExcelWriter 和其他库(如 openpyxl, xlsxwriter)实现更复杂的格式化。
  • 广泛的兼容性:生成的 Excel 文件 (.xlsx, .xls) 可以被大多数电子表格程序读取。

语法:

DataFrame.to_excel(excel_writer, sheet_name='Sheet1', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, startrow=0, startcol=0, engine=None, merge_cells=True, encoding=None, inf_rep='inf', verbose=True, freeze_panes=None)

参数:

  • excel_writer: 字符串或 ExcelWriter 对象。要写入的文件路径或 ExcelWriter 对象。如果提供的是字符串,则会自动创建一个 ExcelWriter 对象。
  • sheet_name: 字符串,默认为 ‘Sheet1’。要写入的工作表名称。
  • na_rep: 字符串,默认为空字符串 ”。用于表示缺失值的字符串。
  • float_format: 字符串,默认为 None。浮点数的格式化字符串。
  • columns: 列表,默认为 None。要导出的列名列表。
  • header: 布尔值或列表,默认为 True。是否包含列名作为文件头。如果是列表,则使用提供的列名。
  • index: 布尔值,默认为 True。是否将索引写入文件。
  • index_label: 字符串或序列,默认为 None。索引列的标签。
  • startrow: 整数,默认为 0。开始写入的行号(从 0 开始计数)。
  • startcol: 整数,默认为 0。开始写入的列号(从 0 开始计数)。
  • engine: {‘openpyxl’, ‘xlsxwriter’, ‘xlwt’},默认为 None。指定使用的 Excel 写入引擎。如果没有提供,则根据文件扩展名自动选择。
  • merge_cells: 布尔值,默认为 True。是否合并具有相同值的单元格。
  • encoding: 字符串,默认为 None。文件编码格式,例如 ‘utf-8’。主要用于旧版的 .xls 文件。
  • inf_rep: 字符串,默认为 ‘inf’。用以表示无穷大的字符串。
  • verbose: 布尔值,默认为 True。是否打印额外信息。
  • freeze_panes: 元组 (row, column),默认为 None。冻结窗格的位置。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [25, 30, 35],
    'City': ['New York', 'Los Angeles', 'Chicago']
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 使用 to_excel() 将 DataFrame 导出为 Excel 文件
df.to_excel('output.xlsx', index=False)  # 不导出索引

# 使用 to_excel() 并指定更多选项
df.to_excel('output_with_options.xlsx', 
            sheet_name='People', 
            index=False, 
            startrow=1, 
            startcol=1,
            freeze_panes=(1, 1))  # 冻结第二行第二列之后的窗格

# 使用 ExcelWriter 在同一个 Excel 文件中创建多个工作表
with pd.ExcelWriter('multiple_sheets.xlsx') as writer:
    df.to_excel(writer, sheet_name='Sheet1', index=False)
    df.to_excel(writer, sheet_name='Sheet2', index=False)

上述代码展示了如何使用 to_excel() 方法根据不同的需求将 DataFrame 导出为 Excel 文件。你可以选择是否导出索引、指定工作表名称、调整起始位置以及添加冻结窗格等功能,以确保生成的文件符合预期。

注意事项:

  • 文件路径:确保提供的文件路径是有效的,并且有适当的权限进行写入操作。
  • 编码问题:对于 .xls 文件,可能需要指定正确的编码以避免乱码问题;对于现代的 .xlsx 文件,通常不需要特别指定编码。
  • 性能考虑:对于大型 DataFrame,考虑分批次导出数据或使用更高效的写入引擎,以减少内存占用和提高速度。
  • 数据一致性:在导出之前检查数据的一致性和完整性,特别是当涉及到日期格式、缺失值处理等。

to_json() 方法

to_json() 是 Pandas 库中 DataFrame 和 Series 对象的一个方法,用于将数据导出为 JSON(JavaScript Object Notation)格式。JSON 是一种轻量级的数据交换格式,易于人类阅读和编写,同时也易于机器解析和生成,因此在不同系统之间传输数据时非常常用。

特点:

  • 灵活的数据序列化:可以轻松地将 DataFrame 或 Series 的数据转换为 JSON 格式。
  • 多种输出格式:支持不同的 JSON 输出格式以适应不同的应用场景。
  • 广泛兼容性:生成的 JSON 数据可以被大多数编程语言和平台解析。

语法:

DataFrame.to_json(path_or_buf=None, orient='columns', date_format='epoch', double_precision=10, force_ascii=True, date_unit='ms', default_handler=None, lines=False, compression='infer')

参数:

  • path_or_buf: 字符串或文件句柄,默认为 None。如果为字符串,则表示要写入的文件路径;如果为文件句柄,则直接写入该对象。如果为 None,则返回一个字符串。
  • orient: {‘split’, ‘records’, ‘index’, ‘columns’, ‘values’, ‘table’},默认为 ‘columns’。定义 JSON 输出的格式:
    • ‘split’: 将索引、列名和数据分开表示。
    • ‘records’: 每个记录作为独立的对象。
    • ‘index’: 索引作为键,每一行的数据作为值。
    • ‘columns’: 列名作为键,每一列的数据作为值。
    • ‘values’: 只包含数据数组。
    • ‘table’: 类似于 ‘dataframe’,但提供了更详细的元数据。
  • date_format: {‘epoch’, ‘iso’},默认为 ‘epoch’。日期时间格式:’epoch’ 表示 Unix 时间戳,’iso’ 表示 ISO 8601 格式的字符串。
  • double_precision: 整数,默认为 10。浮点数的小数位数。
  • force_ascii: 布尔值,默认为 True。是否强制使用 ASCII 编码。
  • date_unit: {‘s’, ‘ms’, ‘us’, ‘ns’},默认为 ‘ms’。当 date_format='epoch' 时使用的单位。
  • default_handler: 函数,默认为 None。处理无法序列化的对象的回调函数。
  • lines: 布尔值,默认为 False。如果为 True,则每个记录作为一行输出。
  • compression: {‘infer’, ‘gzip’, ‘bz2’, ‘zip’, ‘xz’, None},默认为 ‘infer’。压缩类型。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [25, 30, 35],
    'City': ['New York', 'Los Angeles', 'Chicago']
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 使用 to_json() 将 DataFrame 导出为 JSON 字符串
json_str = df.to_json(orient='records')

print("\n导出为 JSON 字符串 (records 格式):")
print(json_str)

# 使用 to_json() 并指定更多选项
json_orient_columns = df.to_json(orient='columns', date_format='iso')

print("\n导出为 JSON 字符串 (columns 格式,ISO 日期) :")
print(json_orient_columns)

# 使用 to_json() 导出到文件并启用行模式
df.to_json('output.json', orient='records', lines=True)

# 使用 to_json() 并指定双精度和ASCII设置
json_custom_settings = df.to_json(double_precision=2, force_ascii=False)

print("\n导出为 JSON 字符串 (自定义双精度和ASCII设置):")
print(json_custom_settings)

上述代码展示了如何使用 to_json() 方法根据不同的需求将 DataFrame 导出为 JSON 格式。你可以选择不同的输出格式、调整日期时间格式、控制浮点数精度以及决定是否强制使用 ASCII 编码等,以确保生成的 JSON 数据符合预期。

注意事项:

  • 文件路径:确保提供的文件路径是有效的,并且有适当的权限进行写入操作。
  • 编码问题:根据目标系统的需要选择正确的编码方式,避免出现乱码问题。
  • 性能考虑:对于大型 DataFrame,考虑使用 lines=True 参数分批次导出数据,以减少内存占用。
  • 数据一致性:在导出之前检查数据的一致性和完整性,特别是当涉及到日期格式、缺失值处理等。

to_sql() 方法

to_sql() 是 Pandas 库中 DataFrame 和 Series 对象的一个方法,用于将数据写入 SQL 数据库表。此方法提供了一种简单而高效的方式,可以直接与多种数据库管理系统(如 SQLite, PostgreSQL, MySQL, Oracle, Microsoft SQL Server 等)交互,从而简化了数据导入过程。通过 to_sql(),可以轻松地将 Pandas 的数据结构保存到关系型数据库中,以便进行更复杂的数据处理、查询和分析。

特点:

  • 直接数据库操作:无需手动构建 SQL 语句即可将数据插入或更新到数据库。
  • 支持多种数据库:兼容多种数据库后端,只需要适当的数据库连接。
  • 灵活的数据映射:能够自动映射 DataFrame 列名到数据库表字段。

语法:

DataFrame.to_sql(name, con, schema=None, if_exists='fail', index=True, index_label=None, chunksize=None, dtype=None, method=None)

参数:

  • name: 字符串。目标数据库表的名称。
  • con: SQLAlchemy engine 或 DBAPI2 connection。与目标数据库的连接对象。
  • schema: 字符串,默认为 None。数据库中的模式(schema)名称。对于某些数据库系统是必需的。
  • if_exists: {‘fail’, ‘replace’, ‘append’},默认为 ‘fail’。指定当目标表已经存在时的行为:
    • ‘fail’: 如果表存在,则抛出异常。
    • ‘replace’: 删除现有表并创建新表。
    • ‘append’: 将数据追加到现有表。
  • index: 布尔值,默认为 True。是否将 DataFrame 的索引写入数据库作为一列。
  • index_label: 字符串或序列,默认为 None。如果 index=True,则可以指定索引列的标签。
  • chunksize: 整数,默认为 None。每次写入的行数。如果设置,将分批次写入以节省内存。
  • dtype: 字典,默认为 None。指定各列的数据类型,键为列名,值为 SQLAlchemy 类型对象。
  • method: {‘multi’, 可调用对象} 或 None,默认为 None。指定插入方法。使用 ‘multi’ 可以在单个 SQL 语句中插入多行,提高效率。

使用示例:

import pandas as pd
from sqlalchemy import create_engine

# 创建一个简单的 DataFrame
data = {
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [25, 30, 35],
    'City': ['New York', 'Los Angeles', 'Chicago']
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 创建数据库连接 (这里以 SQLite 为例)
engine = create_engine('sqlite:///example.db')

# 使用 to_sql() 将 DataFrame 写入 SQLite 数据库
df.to_sql('people', con=engine, if_exists='replace', index=False)

# 使用 to_sql() 并指定更多选项
df.to_sql('people_with_index', con=engine, if_exists='replace', index=True, index_label='id')

# 使用 to_sql() 分批次写入大 DataFrame
df_large = pd.concat([df]*1000)  # 创建一个较大的 DataFrame
df_large.to_sql('large_people', con=engine, if_exists='replace', index=False, chunksize=1000)

# 指定列的数据类型
dtype_mapping = {
    'Name': String(50),
    'Age': Integer(),
    'City': String(50)
}
df.to_sql('typed_people', con=engine, if_exists='replace', index=False, dtype=dtype_mapping)

上述代码展示了如何使用 to_sql() 方法根据不同的需求将 DataFrame 导出到 SQL 数据库。你可以选择是否导出索引、指定表的存在行为、调整批处理大小以及定义各列的数据类型等,以确保数据正确无误地存储到数据库中。

注意事项:

  • 数据库连接:确保提供的数据库连接字符串是有效的,并且有适当的权限进行写入操作。
  • 数据一致性:在写入之前检查数据的一致性和完整性,特别是当涉及到缺失值处理、数据类型转换等。
  • 性能优化:对于大型 DataFrame,考虑使用 chunksize 参数分批次写入数据,或者使用 method='multi' 来提高插入效率。
  • 事务管理:对于支持事务的数据库,可能需要显式地开始和提交事务,特别是在执行批量插入时。

query() 方法

query() 是 Pandas 库中 DataFrame 对象的一个方法,用于根据表达式对数据进行筛选。它提供了一种简洁而直观的方式,通过类似于 SQL 的语法来过滤和操作数据。这种方法不仅可以提高代码的可读性,还能简化复杂的条件逻辑,使数据分析更加高效。

特点:

  • 直观的表达式:使用易于理解的字符串表达式来进行数据筛选。
  • 增强的可读性:相比传统的布尔索引,query() 通常更易读。
  • 支持复杂逻辑:可以处理多条件、括号分组和各种运算符。
  • 变量替换:允许在查询中引用外部变量,从而实现动态查询。

语法:

DataFrame.query(expr, inplace=False, **kwargs)

参数:

  • expr: 字符串。包含查询条件的表达式。
  • inplace: 布尔值,默认为 False。如果为 True,则就地修改 DataFrame;否则返回一个新的 DataFrame。
  • **kwargs: 其他关键字参数将被传递给 pandas.eval() 函数,以控制表达式的评估方式。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'Name': ['Alice', 'Bob', 'Charlie', 'David'],
    'Age': [25, 30, 35, 40],
    'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 使用 query() 筛选年龄大于 30 的行
filtered_df = df.query('Age > 30')

print("\n筛选后 DataFrame (年龄大于 30):")
print(filtered_df)

# 使用 query() 并结合多个条件
multi_condition_df = df.query('Age > 30 and City == "Chicago"')

print("\n筛选后 DataFrame (年龄大于 30 且城市为 Chicago):")
print(multi_condition_df)

# 使用 query() 引用外部变量
min_age = 30
external_var_df = df.query('Age >= @min_age')

print(f"\n筛选后 DataFrame (年龄大于等于 {min_age}):")
print(external_var_df)

# 使用 query() 进行列间的比较
column_comparison_df = df.query('Age > Name.count()')

print("\n筛选后 DataFrame (年龄大于名字长度):")
print(column_comparison_df)  # 注意这里是一个假设性的例子,实际上 Age 和 Name.count() 不会直接比较

上述代码展示了如何使用 query() 方法根据不同的条件筛选 DataFrame 中的数据。你可以构建简单的单条件查询、组合多个条件、引用外部变量以及执行列间比较等,以满足特定的数据分析需求。

注意事项:

  • 表达式正确性:确保提供的表达式是有效的,并遵循 Pandas 表达式的语法规则。
  • 性能考虑:对于大型 DataFrame,复杂的查询可能会导致性能下降。在这种情况下,可以考虑优化查询逻辑或使用其他更高效的筛选方法。
  • 变量引用:当使用外部变量时,请确保使用 @ 符号前缀,并且该变量在作用域内可用。
  • 避免冲突:注意不要让查询表达式中的变量名与 DataFrame 的列名发生冲突,以免引起意外的结果。

duplicated() 方法

duplicated() 是 Pandas 库中 DataFrame 和 Series 对象的一个方法,用于标识数据集中重复的行或元素。它返回一个布尔型序列(Series),其中每个值表示对应的行或元素是否是第一次出现之后的重复项。此方法对于发现和处理数据中的冗余信息非常有用,可以帮助确保数据集的唯一性和准确性。

特点:

  • 识别重复项:可以快速找到数据集中的重复条目。
  • 灵活的重复定义:可以根据全部列或指定列来判断重复。
  • 控制保留选项:可以选择保留首次出现、最后一次出现或者完全移除所有重复。

语法:

DataFrame.duplicated(subset=None, keep='first')

参数:

  • subset: 标签或标签列表,默认为 None。要检查重复的列名或列名列表。如果为 None,则使用所有列。
  • keep: {‘first’, ‘last’, False},默认为 ‘first’。如何标记重复:
    • ‘first’: 仅将首次出现后的重复项标记为 True。
    • ‘last’: 仅将最后一次出现前的重复项标记为 True。
    • False: 将所有重复项都标记为 True。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'Name': ['Alice', 'Bob', 'Charlie', 'Alice', 'David', 'Bob'],
    'Age': [25, 30, 35, 25, 40, 30],
    'City': ['New York', 'Los Angeles', 'Chicago', 'New York', 'Houston', 'Los Angeles']
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 使用 duplicated() 查找所有列上的重复行
duplicates_all_columns = df.duplicated()

print("\n所有列上重复行的布尔序列:")
print(duplicates_all_columns)

# 使用 duplicated() 并指定子集列
duplicates_subset = df.duplicated(subset=['Name'])

print("\n根据 'Name' 列查找重复行的布尔序列:")
print(duplicates_subset)

# 使用 duplicated() 并更改保留选项
duplicates_keep_last = df.duplicated(keep='last')

print("\n保留最后出现的重复行的布尔序列:")
print(duplicates_keep_last)

# 使用 duplicated() 不保留任何重复
all_duplicates = df.duplicated(keep=False)

print("\n不保留任何重复行的布尔序列:")
print(all_duplicates)

# 结合 duplicated() 和 drop_duplicates() 删除重复行
df_unique = df.drop_duplicates(subset=['Name'], keep='first')

print("\n删除 'Name' 列上的重复行后的 DataFrame:")
print(df_unique)

上述代码展示了如何使用 duplicated() 方法根据不同的需求标识 DataFrame 中的重复行。你可以选择基于全部列或特定列进行重复检测,并调整保留策略以适应具体的数据清理任务。

注意事项:

  • 理解逻辑:确保理解 keep 参数的不同取值对结果的影响,以便正确地处理重复数据。
  • 性能考虑:对于大型 DataFrame,duplicated() 的计算可能较为耗时。在这种情况下,可以先评估是否有更高效的方法或优化查询逻辑。
  • 结合其他方法:duplicated() 常与 drop_duplicates() 一起使用,以直接从 DataFrame 中移除重复行。

drop_duplicates() 方法

drop_duplicates() 是 Pandas 库中 DataFrame 和 Series 对象的一个方法,用于从数据集中移除重复的行或元素。它基于 duplicated() 方法来识别重复项,并返回一个新的数据集,其中只保留第一次出现的条目(或根据指定逻辑保留)。此方法对于清理数据、确保唯一性和提高数据分析的准确性非常有用。

特点:

  • 移除重复项:可以有效地从数据集中删除重复的行或元素。
  • 灵活的重复定义:可以根据全部列或指定列来判断并移除重复。
  • 控制保留选项:可以选择保留首次出现、最后一次出现或者完全移除所有重复。
  • 保持索引不变:默认情况下,原始索引将被保留,除非明确指定了重置索引。

语法:

DataFrame.drop_duplicates(subset=None, keep='first', inplace=False, ignore_index=False)

参数:

  • subset: 标签或标签列表,默认为 None。要检查重复的列名或列名列表。如果为 None,则使用所有列。
  • keep: {‘first’, ‘last’, False},默认为 ‘first’。如何处理重复:
    • ‘first’: 仅保留首次出现的非重复项。
    • ‘last’: 仅保留最后一次出现的非重复项。
    • False: 移除所有重复项,不保留任何副本。
  • inplace: 布尔值,默认为 False。如果为 True,则就地修改 DataFrame;否则返回一个新的 DataFrame。
  • ignore_index: 布尔值,默认为 False。如果为 True,则忽略原始索引并生成一个默认整数索引。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'Name': ['Alice', 'Bob', 'Charlie', 'Alice', 'David', 'Bob'],
    'Age': [25, 30, 35, 25, 40, 30],
    'City': ['New York', 'Los Angeles', 'Chicago', 'New York', 'Houston', 'Los Angeles']
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 使用 drop_duplicates() 移除所有列上的重复行
df_all_columns = df.drop_duplicates()

print("\n移除所有列上重复行后的 DataFrame:")
print(df_all_columns)

# 使用 drop_duplicates() 并指定子集列
df_subset = df.drop_duplicates(subset=['Name'])

print("\n根据 'Name' 列移除重复行后的 DataFrame:")
print(df_subset)

# 使用 drop_duplicates() 并更改保留选项
df_keep_last = df.drop_duplicates(keep='last')

print("\n保留最后出现的非重复行后的 DataFrame:")
print(df_keep_last)

# 使用 drop_duplicates() 不保留任何重复
df_no_duplicates = df.drop_duplicates(keep=False)

print("\n不保留任何重复行后的 DataFrame:")
print(df_no_duplicates)

# 使用 drop_duplicates() 并重置索引
df_reset_index = df.drop_duplicates(ignore_index=True)

print("\n移除重复行并重置索引后的 DataFrame:")
print(df_reset_index)

上述代码展示了如何使用 drop_duplicates() 方法根据不同的需求从 DataFrame 中移除重复行。你可以选择基于全部列或特定列进行重复检测,并调整保留策略以适应具体的数据清理任务。此外,还可以选择是否就地修改原始 DataFrame 或者创建新的 DataFrame。

注意事项:

  • 理解逻辑:确保理解 keep 参数的不同取值对结果的影响,以便正确地处理重复数据。
  • 性能考虑:对于大型 DataFrame,drop_duplicates() 的计算可能较为耗时。在这种情况下,可以先评估是否有更高效的方法或优化查询逻辑。
  • 结合其他方法:drop_duplicates() 可以与 duplicated() 结合使用,以先标识后移除重复行。
  • 索引处理:注意 ignore_index 参数的选择,特别是当你需要保留原始索引结构时。

set_index() 方法

set_index() 是 Pandas 库中 DataFrame 对象的一个方法,用于将一个或多个现有列设置为 DataFrame 的索引。此方法对于重新组织数据结构、提高查询效率以及进行基于索引的操作非常有用。通过 set_index(),可以方便地指定哪些列应该作为行标签,从而改善数据的访问和操作方式。

特点:

  • 索引重构:可以使用一列或多列创建新的行索引。
  • 多级索引支持:允许创建具有多层(层次化)索引的数据结构。
  • 灵活的参数控制:提供多种参数选项以适应不同的需求。

语法:

DataFrame.set_index(keys, drop=True, append=False, inplace=False, verify_integrity=False)

参数:

  • keys: 标签或标签列表。要设置为新索引的列名或列名列表。
  • drop: 布尔值,默认为 True。如果为 True,则在设置为索引后删除这些列;如果为 False,则保留这些列。
  • append: 布尔值,默认为 False。如果为 True,则附加新索引而不是替换现有的索引,形成多级索引。
  • inplace: 布尔值,默认为 False。如果为 True,则就地修改 DataFrame;否则返回一个新的 DataFrame。
  • verify_integrity: 布尔值,默认为 False。如果为 True,则检查新索引是否包含重复标签,并在发现重复时抛出异常。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'Name': ['Alice', 'Bob', 'Charlie', 'David'],
    'Age': [25, 30, 35, 40],
    'City': ['New York', 'Los Angeles', 'Chicago', 'Houston']
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 使用 set_index() 将 'Name' 列设置为索引
df_name_index = df.set_index('Name')

print("\n将 'Name' 列设置为索引后的 DataFrame:")
print(df_name_index)

# 使用 set_index() 并保留原来的列
df_keep_columns = df.set_index('Name', drop=False)

print("\n将 'Name' 列设置为索引但保留原列后的 DataFrame:")
print(df_keep_columns)

# 使用 set_index() 创建多级索引
df_multi_index = df.set_index(['Name', 'City'])

print("\n创建多级索引 (Name 和 City) 后的 DataFrame:")
print(df_multi_index)

# 使用 set_index() 并附加到现有索引
df_append_index = df.set_index('Age', append=True)

print("\n附加 'Age' 列到现有索引后的 DataFrame:")
print(df_append_index)

# 使用 set_index() 并验证索引完整性
try:
    df_unique_index = df.set_index('City', verify_integrity=True)
except ValueError as e:
    print(f"\n尝试设置唯一索引失败: {e}")

上述代码展示了如何使用 set_index() 方法根据不同的需求将 DataFrame 中的一列或多列设置为新的行索引。你可以选择是否删除用作索引的列、创建多级索引、附加到现有索引,还可以选择是否验证新索引的唯一性。

注意事项:

  • 索引唯一性:当设置新的索引时,特别是当 verify_integrity=True 时,请确保提供的列没有重复值,以避免引发错误。
  • 性能考虑:对于大型 DataFrame,更改索引可能会消耗较多资源。因此,在执行此操作之前,应评估其对性能的影响。
  • 索引层次结构:创建多级索引可以增加数据的复杂性,但也提供了更强大的数据切片和聚合功能。在设计数据结构时应权衡利弊。
  • 后续操作:一旦设置了新的索引,后续的数据操作(如排序、分组等)可能会受到影响。请根据需要调整相应的逻辑。

reset_index() 方法

reset_index() 是 Pandas 库中 DataFrame 对象的一个方法,用于重置行索引为默认的整数索引,并可以选择将原来的索引添加为一列或多列。此方法对于恢复数据结构、准备数据进行进一步处理或与其他数据集合并非常有用。通过 reset_index(),可以方便地取消之前设置的任何自定义索引,使数据更易于操作和理解。

特点:

  • 恢复默认索引:将行标签重置为从 0 开始的整数序列。
  • 保存原索引:可以选择是否保留原始索引作为新列。
  • 处理多级索引:如果存在层次化索引,可以将其展开成多个列。

语法:

DataFrame.reset_index(level=None, drop=False, inplace=False, col_level=0, col_fill='')

参数:

  • level: 整数或标签或整数列表或标签列表,默认为 None。指定要重置的索引级别(仅对多级索引有效)。如果为 None,则重置所有级别的索引。
  • drop: 布尔值,默认为 False。如果为 True,则不将旧索引添加为新列;如果为 False,则将旧索引作为新列保留在 DataFrame 中。
  • inplace: 布尔值,默认为 False。如果为 True,则就地修改 DataFrame;否则返回一个新的 DataFrame。
  • col_level: 整数或字符串,默认为 0。当有多个列名层级时,指定在哪一层级上创建新的列名。
  • col_fill: 字符串,默认为空字符串 ”。当有多个列名层级且新列名需要填充时,指定用什么值填充。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [25, 30, 35],
    'City': ['New York', 'Los Angeles', 'Chicago']
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 设置 'Name' 列为索引
df_set_index = df.set_index('Name')

print("\n将 'Name' 列设置为索引后的 DataFrame:")
print(df_set_index)

# 使用 reset_index() 恢复默认索引并保留原索引
df_reset = df_set_index.reset_index()

print("\n恢复默认索引并保留原索引后的 DataFrame:")
print(df_reset)

# 使用 reset_index() 不保留原索引
df_reset_drop = df_set_index.reset_index(drop=True)

print("\n恢复默认索引但不保留原索引后的 DataFrame:")
print(df_reset_drop)

# 使用 reset_index() 处理多级索引
df_multi_index = df.set_index(['Name', 'City'])

print("\n创建多级索引 (Name 和 City) 后的 DataFrame:")
print(df_multi_index)

df_reset_multi = df_multi_index.reset_index()

print("\n重置多级索引后的 DataFrame:")
print(df_reset_multi)

# 使用 reset_index() 并指定索引级别
df_reset_specific_level = df_multi_index.reset_index(level='City')

print("\n重置特定级别索引后的 DataFrame:")
print(df_reset_specific_level)

上述代码展示了如何使用 reset_index() 方法根据不同的需求重置 DataFrame 的行索引。你可以选择是否保留旧索引作为新列、处理多级索引,还可以指定要重置的索引级别。

注意事项:

  • 索引保留:根据 drop 参数的选择,决定是否将旧索引保留在 DataFrame 中作为一个新列。这取决于你后续的数据处理需求。
  • 性能考虑:对于大型 DataFrame,reset_index() 的计算可能较为耗时。在这种情况下,可以评估是否有更高效的方法或优化查询逻辑。
  • 多级索引处理:当你有一个多级索引时,可以使用 level 参数来指定只重置某些级别的索引,或者完全重置所有级别的索引。
  • 就地修改 vs 新对象:使用 inplace 参数来决定是就地修改现有 DataFrame 还是创建一个新的 DataFrame。通常建议不要频繁就地修改,以保持数据版本的历史记录。

transpose() 方法

transpose() 是 Pandas 库中 DataFrame 和 Series 对象的一个方法,用于将数据的行和列进行转置。即原来的行变成列,原来的列变成行。此方法对于改变数据的视角、准备数据进行特定类型的分析或与其他数据集对齐非常有用。

特点:

  • 行列转换:可以快速地交换数据的行和列。
  • 保持索引结构:转置后,原始的行索引变为列标签,而原始的列标签变为行索引。
  • 适用于多种数据类型:不仅限于数值型数据,还可以应用于字符串、日期等其他类型的数据。

语法:

DataFrame.transpose(*args, **kwargs)

参数:

  • *args, **kwargs: 这些参数是为了与 NumPy 兼容而保留的,但在 Pandas 的 transpose() 方法中通常不使用。

使用示例:

import pandas as pd

# 创建一个简单的 DataFrame
data = {
    'Name': ['Alice', 'Bob', 'Charlie'],
    'Age': [25, 30, 35],
    'City': ['New York', 'Los Angeles', 'Chicago']
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)

# 使用 transpose() 转置 DataFrame
df_transposed = df.transpose()

print("\n转置后的 DataFrame:")
print(df_transposed)

# 演示转置后的索引和列名变化
print("\n转置后的新行索引 (原列名):")
print(df_transposed.index)

print("\n转置后的新列名 (原行索引):")
print(df_transposed.columns)

# 如果需要将转置后的结果再次转置回原来的形式,可以再次调用 transpose()
df_original = df_transposed.transpose()

print("\n再次转置恢复为原始形式的 DataFrame:")
print(df_original)

# 注意:如果 DataFrame 包含多级索引或多级列,转置会相应地处理这些复杂的索引结构。

上述代码展示了如何使用 transpose() 方法根据不同的需求转置 DataFrame 的行和列。你可以看到,转置操作改变了数据的结构,使得原本的行变成了列,而原本的列则变成了行。这对于某些数据分析任务特别有用,比如当您想要以不同的方式查看数据或者准备数据进行特定类型的处理时。

注意事项:

  • 数据完整性:在转置过程中,确保您的数据不会丢失任何信息。特别是注意处理好缺失值(NaN),因为它们在转置前后的位置会发生变化。
  • 性能考虑:对于大型 DataFrame,转置操作可能会消耗较多资源。因此,在执行此操作之前,应评估其对性能的影响。
  • 索引和列名管理:转置后,原始的行索引变为列标签,而原始的列标签变为行索引。如果您有特殊的索引或列名格式要求,请在转置后调整它们。
  • 多级索引处理:如果您的 DataFrame 具有多级索引或多级列,则转置也会相应地处理这些复杂的索引结构。确保了解这些复杂结构在转置前后的变化。

结尾

到这里基本的dataframe方法属函数都简单介绍了一下,其中比较重要我会单独开一篇文章讲解。大家期待一下吧。

完结撒花~

文末声明:

您必须遵守关于,您可以随意转发/引用,但要注明原作者Leon或设置本文跳转连接,并且您必须在文中包含或提醒浏览者遵守作者声明
欢迎关注公众号获取第二手文章!高效工作法

暂无评论

发送评论 编辑评论


				
上一篇
下一篇