9Python的Pandas:数据合并与对比_pandas对比两列数据

在处理数据时,Pandas 提供了非常强大的工具来进行数据的合并和对比。以下是常用的一些操作方法:

1.数据追加(Append)

在 Pandas 中,数据追加可以通过多种方式实现,具体取决于你希望追加数据的方式。下面是几种常见的方法:

1.1. 使用 append 方法追加数据

append 方法允许你将一个 DataFrame 追加到另一个 DataFrame 的末尾。它返回一个新的 DataFrame,原始 DataFrame 保持不变。

import pandas as pd

# 示例数据
df1 = pd.DataFrame({
    'key': ['A', 'B', 'C'],
    'value': [1, 2, 3]
})

df2 = pd.DataFrame({
    'key': ['D', 'E'],
    'value': [4, 5]
})

# 追加数据
df3 = df1.append(df2, ignore_index=True)
print(df3)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • ignore_index=True:重新索引合并后的 DataFrame。

1.2. 使用 concat 方法追加数据

concat 方法不仅可以用于合并数据,还可以用于追加数据。通过指定 axis=0,你可以在行方向上追加数据。

# 使用 concat 追加数据
df4 = pd.concat([df1, df2], axis=0, ignore_index=True)
print(df4)
  • 1
  • 2
  • 3
  • axis=0:按行追加数据。
  • ignore_index=True:重新索引合并后的 DataFrame。

1.3. 使用 loc 方法追加单行数据

如果你只想追加一行数据,可以使用 loc 方法。

# 追加单行数据
df1.loc[len(df1)] = ['D', 4]
print(df1)
  • 1
  • 2
  • 3
  • loc 方法可以直接在现有的 DataFrame 末尾追加一行。

1.4. 使用 assign 方法追加新的列数据

如果需要为 DataFrame 追加新的列,可以使用 assign 方法。

# 追加新列
df1 = df1.assign(new_value=[10, 20, 30])
print(df1)
  • 1
  • 2
  • 3
  • assign 方法用于在 DataFrame 中添加新列,或对现有列进行重新赋值。

2. 多文件合并,目录文件合并

在 Pandas 中,可以使用 concatmerge 等方法将多个文件的数据合并在一起。如果你有多个文件,并且希望将这些文件的数据合并成一个 DataFrame,可以按照以下步骤进行操作。

2.1. 合并多个文件的数据

假设你有多个 CSV 文件,需要将它们合并成一个 DataFrame。你可以使用以下方法:

示例:合并多个 CSV 文件

import pandas as pd
import os

# 定义文件路径
directory = '/path/to/csv/files'

# 获取目录下所有CSV文件
all_files = [os.path.join(directory, f) for f in os.listdir(directory) if f.endswith('.csv')]

# 将所有文件合并成一个DataFrame
df_list = [pd.read_csv(file) for file in all_files]
merged_df = pd.concat(df_list, ignore_index=True)

print(merged_df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • os.listdir(directory):列出指定目录下的所有文件。
  • pd.read_csv(file):读取 CSV 文件。
  • pd.concat(df_list, ignore_index=True):将所有 DataFrame 合并为一个。

3.2. 合并多个 Excel 文件中的表

如果你有多个 Excel 文件,每个文件中有一个或多个表需要合并,可以使用 pd.read_excel 来读取数据并进行合并。

示例:合并多个 Excel 文件中的表

import pandas as pd
import os

# 定义文件路径
directory = '/path/to/excel/files'

# 获取目录下所有Excel文件
all_files = [os.path.join(directory, f) for f in os.listdir(directory) if f.endswith('.xlsx')]

# 将所有文件合并成一个DataFrame
df_list = []
for file in all_files:
    xls = pd.ExcelFile(file)
    for sheet_name in xls.sheet_names:
        df = pd.read_excel(xls, sheet_name=sheet_name)
        df_list.append(df)

merged_df = pd.concat(df_list, ignore_index=True)

print(merged_df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • pd.ExcelFile(file):加载 Excel 文件。
  • xls.sheet_names:获取 Excel 文件中的所有表名。
  • pd.read_excel(xls, sheet_name=sheet_name):读取指定表的数据。

3.3. 合并目录下所有的 JSON 文件

如果你有多个 JSON 文件并需要将它们合并在一起,以下是方法:

示例:合并多个 JSON 文件

import pandas as pd
import os

# 定义文件路径
directory = '/path/to/json/files'

# 获取目录下所有JSON文件
all_files = [os.path.join(directory, f) for f in os.listdir(directory) if f.endswith('.json')]

# 将所有文件合并成一个DataFrame
df_list = [pd.read_json(file) for file in all_files]
merged_df = pd.concat(df_list, ignore_index=True)

print(merged_df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • pd.read_json(file):读取 JSON 文件。
  • 其他步骤与 CSV 文件的合并类似。

3.4. 根据文件夹合并多个数据集

如果你希望根据文件夹结构合并数据集,例如每个子文件夹中的文件代表一个不同的组数据,你可以通过遍历文件夹的方式进行合并。

示例:按文件夹合并数据

import pandas as pd
import os

# 定义主目录路径
main_directory = '/path/to/main/folder'

# 创建一个空的DataFrame列表
df_list = []

# 遍历主目录下的每个子文件夹
for folder_name in os.listdir(main_directory):
    folder_path = os.path.join(main_directory, folder_name)
    if os.path.isdir(folder_path):
        # 获取子文件夹中的所有文件
        for file_name in os.listdir(folder_path):
            if file_name.endswith('.csv'):
                file_path = os.path.join(folder_path, file_name)
                df = pd.read_csv(file_path)
                df['folder'] = folder_name  # 添加一列标记数据来源
                df_list.append(df)

# 合并所有DataFrame
merged_df = pd.concat(df_list, ignore_index=True)

print(merged_df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • os.path.isdir(folder_path):检查路径是否为目录。
  • 在合并过程中,可以添加标记列(如上例中的 folder 列)以区分数据来源。

4. 数据合并(Merge

在 Pandas 中,merge 是一个非常强大的函数,用于合并两个 DataFrame,类似于 SQL 中的 JOIN 操作。通过 merge,你可以指定连接的键、连接的方式以及如何处理合并后的数据。

4.1.基本用法

merge 的基本语法如下:

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, suffixes=('_x', '_y'))
  • 1
  • leftright: 需要合并的两个 DataFrame。
  • how: 合并的方式,常用的有 'inner''outer''left''right'
    • 'inner': 默认方式,取两者交集(即只保留在两者中都有的键)。
    • 'outer': 取两者并集(即保留所有键,缺失值填充为 NaN)。
    • 'left': 左连接,保留左表的所有数据。
    • 'right': 右连接,保留右表的所有数据。
  • on: 指定用作键的列名,通常适用于两个 DataFrame 都有相同的列名。
  • left_onright_on: 如果两个 DataFrame 的列名不同,可以分别指定它们的列名。
  • suffixes: 用于在合并后产生列名冲突时指定后缀。

4.2.示例

4.2.1. 基于单一键的合并

import pandas as pd

# 示例数据
df1 = pd.DataFrame({
    'key': ['A', 'B', 'C', 'D'],
    'value': [1, 2, 3, 4]
})

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

# 使用 key 列进行内连接
merged_df = pd.merge(df1, df2, on='key', how='inner')
print(merged_df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

在这个例子中,df1df2key 列上进行内连接,只保留两个 DataFrame 中都包含的键(即 BD)。

4.1.2. 左连接

# 左连接,保留左表的所有数据
left_merged_df = pd.merge(df1, df2, on='key', how='left')
print(left_merged_df)
  • 1
  • 2
  • 3

左连接保留了 df1 中的所有数据,即使 df2 中没有对应的 key,相应的 value 会用 NaN 填充。

4.1.3. 右连接

# 右连接,保留右表的所有数据
right_merged_df = pd.merge(df1, df2, on='key', how='right')
print(right_merged_df)
  • 1
  • 2
  • 3

右连接保留了 df2 中的所有数据,即使 df1 中没有对应的 key,相应的 value 会用 NaN 填充。

4.1.4. 全连接(外连接)

# 外连接,保留两表的并集
outer_merged_df = pd.merge(df1, df2, on='key', how='outer')
print(outer_merged_df)
  • 1
  • 2
  • 3

外连接保留了 df1df2 中所有的键,没有对应关系的数据会用 NaN 填充。

4.1.5. 基于不同列的合并

如果两个 DataFrame 的键列名称不同,可以使用 left_onright_on 参数。

df1 = pd.DataFrame({
    'key1': ['A', 'B', 'C', 'D'],
    'value1': [1, 2, 3, 4]
})

df2 = pd.DataFrame({
    'key2': ['B', 'D', 'E', 'F'],
    'value2': [5, 6, 7, 8]
})

# 基于不同列名进行合并
merged_df_diff_keys = pd.merge(df1, df2, left_on='key1', right_on='key2', how='inner')
print(merged_df_diff_keys)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

4.1.6. 处理合并后列名冲突

在合并时,如果两个 DataFrame 有相同的列名(除了用于连接的键列),可以通过 suffixes 参数指定后缀以区分它们。

df1 = pd.DataFrame({
    'key': ['A', 'B', 'C', 'D'],
    'value': [1, 2, 3, 4]
})

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

# 合并时,避免列名冲突
merged_df_suffix = pd.merge(df1, df2, on='key', how='outer', suffixes=('_left', '_right'))
print(merged_df_suffix)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

5. 数据对比(compare)

Pandas 的 compare 方法可以帮助你比较两个 DataFrame,找出它们之间的差异。这在你需要对比两个版本的数据时非常有用,比如找出哪些数据发生了变化。

5.1.compare 方法的基本用法

compare 方法返回一个 DataFrame,显示两个 DataFrame 在相同索引和列处的不同值。它默认只显示差异部分,并用多层索引标记来自于哪个 DataFrame。

import pandas as pd

# 示例数据
df1 = pd.DataFrame({
    'A': ['A0', 'A1', 'A2', 'A3'],
    'B': ['B0', 'B1', 'B2', 'B3'],
    'C': ['C0', 'C1', 'C2', 'C3']
})

df2 = pd.DataFrame({
    'A': ['A0', 'A1_changed', 'A2', 'A3_changed'],
    'B': ['B0', 'B1', 'B2_changed', 'B3'],
    'C': ['C0', 'C1', 'C2', 'C3_changed']
})

# 使用 compare 方法比较两个 DataFrame
comparison_df = df1.compare(df2)
print(comparison_df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

5.2.主要参数

  • keep_shape: 默认值为 False。如果设置为 True,返回的 DataFrame 将保留与原始 DataFrame 相同的形状。没有变化的地方会填充为 NaN

    comparison_df = df1.compare(df2, keep_shape=True)
    print(comparison_df)
    
    • 1
    • 2
  • keep_equal: 默认值为 False。如果设置为 True,返回的 DataFrame 中将显示没有变化的部分。

    comparison_df = df1.compare(df2, keep_equal=True)
    print(comparison_df)
    
    • 1
    • 2
  • align_axis: 默认值为 1(列)。指定比较结果的对齐方式,0 为按行对齐,1 为按列对齐。

    comparison_df = df1.compare(df2, align_axis=0)
    print(comparison_df)
    
    • 1
    • 2

5.3.示例结果分析

# 结果
      A                 B                 C            
  self    other    self    other    self    other
1    A1    A1_changed    B1    B1    C1    C1
3    A3    A3_changed    B3    B3    C3    C3_changed
  • 1
  • 2
  • 3
  • 4
  • 5

在上面的示例中:

  • self 列表示 df1 的值。
  • other 列表示 df2 的值。
  • 行索引 1 和 3 表示这些行的值发生了变化。

5.4.使用场景

  • 数据版本控制: 对比不同版本的数据,找出哪些数据发生了变化。
  • 质量控制: 比较实验数据或测试数据,找出差异。
  • 数据清理: 确定数据合并或处理过程中的错误或不一致。

compare 方法非常适合在两个类似的 DataFrame 中找出细微的差异,并能清晰地展示这些差异的位置和变化情况。如果你有更具体的需求或例子,我可以帮助你进一步探讨。

6. 数据拼接(Concatenate)

在 Pandas 中,compare 方法用于比较两个 DataFrame 的差异。它能高效地找出两个 DataFrame 中相同位置上的不同值,并返回一个包含这些差异的 DataFrame。

6.1.基本用法

compare 方法用于显示两个 DataFrame 在相同索引和列处的不同值,并通过多层索引标记这些差异来自哪个 DataFrame。

import pandas as pd

# 示例数据
df1 = pd.DataFrame({
    'A': ['A0', 'A1', 'A2', 'A3'],
    'B': ['B0', 'B1', 'B2', 'B3'],
    'C': ['C0', 'C1', 'C2', 'C3']
})

df2 = pd.DataFrame({
    'A': ['A0', 'A1_changed', 'A2', 'A3_changed'],
    'B': ['B0', 'B1', 'B2_changed', 'B3'],
    'C': ['C0', 'C1', 'C2', 'C3_changed']
})

# 比较两个 DataFrame 的不同
comparison_df = df1.compare(df2)
print(comparison_df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

6.2.结果解析

在上述代码中,compare 返回的结果将展示 df1df2 之间的不同点。结果中,self 表示 df1 中的值,other 表示 df2 中的值。

      A                B                C            
   self      other   self      other   self      other
1   A1   A1_changed   B1          B1   C1          C1
3   A3   A3_changed   B3          B3   C3   C3_changed
  • 1
  • 2
  • 3
  • 4
  • 行索引 1 和 3 表示在这些行中,df1df2 对应位置的值不同。
  • selfother 用于分别展示两个 DataFrame 在相同位置的值。

6.3.主要参数

  • keep_shape: 默认为 False。如果设置为 True,返回的 DataFrame 将保留与原始 DataFrame 相同的形状,未发生变化的位置将填充为 NaN。

    comparison_df = df1.compare(df2, keep_shape=True)
    print(comparison_df)
    
    • 1
    • 2
  • keep_equal: 默认为 False。如果设置为 True,返回的 DataFrame 中将包含未发生变化的部分。

    comparison_df = df1.compare(df2, keep_equal=True)
    print(comparison_df)
    
    • 1
    • 2
  • align_axis: 默认为 1(按列对齐)。可以设置为 0 以按行对齐。

    comparison_df = df1.compare(df2, align_axis=0)
    print(comparison_df)
    
    • 1
    • 2

6.4.详细示例

假设你有两个版本的实验数据,想找出哪些数据发生了变化。compare 方法可以帮助你清晰地展示这些变化:

# 详细示例
df1 = pd.DataFrame({
    'Experiment': ['Exp1', 'Exp2', 'Exp3', 'Exp4'],
    'Result': [0.95, 0.85, 0.78, 0.65]
})

df2 = pd.DataFrame({
    'Experiment': ['Exp1', 'Exp2', 'Exp3', 'Exp4'],
    'Result': [0.95, 0.82, 0.78, 0.67]
})

comparison_df = df1.compare(df2)
print(comparison_df)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

输出结果将显示 Exp2Exp4 的结果发生了变化:

       Result       
         self other
1        0.85  0.82
3        0.65  0.67
  • 1
  • 2
  • 3
  • 4