在处理数据时,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 中,可以使用 concat
、merge
等方法将多个文件的数据合并在一起。如果你有多个文件,并且希望将这些文件的数据合并成一个 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
left
和right
: 需要合并的两个 DataFrame。how
: 合并的方式,常用的有'inner'
、'outer'
、'left'
、'right'
。'inner'
: 默认方式,取两者交集(即只保留在两者中都有的键)。'outer'
: 取两者并集(即保留所有键,缺失值填充为 NaN)。'left'
: 左连接,保留左表的所有数据。'right'
: 右连接,保留右表的所有数据。
on
: 指定用作键的列名,通常适用于两个 DataFrame 都有相同的列名。left_on
和right_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
在这个例子中,df1
和 df2
在 key
列上进行内连接,只保留两个 DataFrame 中都包含的键(即 B
和 D
)。
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
外连接保留了 df1
和 df2
中所有的键,没有对应关系的数据会用 NaN
填充。
4.1.5. 基于不同列的合并
如果两个 DataFrame 的键列名称不同,可以使用 left_on
和 right_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
返回的结果将展示 df1
和 df2
之间的不同点。结果中,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 表示在这些行中,
df1
和df2
对应位置的值不同。 self
和other
用于分别展示两个 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
输出结果将显示 Exp2
和 Exp4
的结果发生了变化:
Result
self other
1 0.85 0.82
3 0.65 0.67
- 1
- 2
- 3
- 4