
在日常的数据处理任务中,我们经常会遇到需要从多个分散的文本文件中提取信息,并根据某些共同的标识符将它们关联起来的场景。例如,你可能有一个包含IP地址列表的文件,一个记录IP地址与MAC地址映射关系的文件,以及一个包含MAC地址与交换机端口对应关系的文件。我们的目标是,给定一个IP地址列表,找出每个IP对应的MAC地址,进而找到该MAC地址所连接的交换机端口,并最终输出IP、MAC地址和端口的对应关系。
手动通过文件迭代和字符串匹配来完成这项任务不仅效率低下,而且代码复杂、易出错。当文件规模增大时,这种方法几乎不可行。幸运的是,Python的Pandas库提供了强大的数据结构(DataFrame)和数据操作工具,可以极大地简化此类任务。
Pandas库的核心是DataFrame,它是一个二维的、表格型的数据结构,类似于电子表格或SQL数据库中的表。Pandas提供了丰富的函数来读取各种数据源、进行数据清洗、转换、合并以及分析。对于多文件数据关联问题,我们可以将每个文件加载为DataFrame,然后使用merge方法像SQL的JOIN操作一样将它们连接起来。
首先,我们需要将提供的三个文本文件(file1.txt, file2.txt, file3.txt)加载到Pandas DataFrame中。pd.read_csv是加载文本文件的主要函数,通过调整其参数可以适应各种文件格式。
假设我们的文件内容如下:
file1.txt
1.1.1.1 1.1.1.2 1.1.1.3 1.1.1.6 1.1.1.11
file2.txt
Protocol Address Age (min) Addr Type Interface Internet 1.1.1.1 5 6026.aa11.1111 A Ethernet1/49 Internet 1.1.1.2 - 0006.f2d2.2d2f A Vlan1 Internet 1.1.1.3 - 6026.aa33.3333 A Vlan1 Internet 1.1.1.4 0 Incomplete A Internet 1.1.1.5 0 Incomplete A Internet 1.1.1.6 64 fa16.6edb.6666 A Vlan1 Internet 1.1.1.11 23 fa16.7e7d.7777 A Vlan1
file3.txt
Unicast Entries vlan mac address type protocols port ---------+---------------+--------+---------------------+------------------------- 1 6026.aa11.1111 static ip,ipx,assigned,other Switch 1 0006.f2d2.2d2f dynamic ip,ipx,assigned,other Ethernet1/24 1 6026.aa33.3333 dynamic ip,ipx,assigned,other Ethernet1/12 1 fa16.6edb.6666 dynamic ip,ipx,assigned,other Ethernet1/8 1 fa16.7e7d.7777 dynamic ip,ipx,assigned,other Ethernet1/10
现在,我们来加载这些文件:
import pandas as pd
import io # 用于模拟文件读取,实际应用中直接使用文件名
# 模拟文件内容,实际应用中会直接使用 pd.read_csv('file_name.txt', ...)
file1_content = """1.1.1.1
1.1.1.2
1.1.1.3
1.1.1.6
1.1.1.11"""
file2_content = """Protocol Address Age (min) Addr Type Interface
Internet 1.1.1.1 5 6026.aa11.1111 A Ethernet1/49
Internet 1.1.1.2 - 0006.f2d2.2d2f A Vlan1
Internet 1.1.1.3 - 6026.aa33.3333 A Vlan1
Internet 1.1.1.4 0 Incomplete A
Internet 1.1.1.5 0 Incomplete A
Internet 1.1.1.6 64 fa16.6edb.6666 A Vlan1
Internet 1.1.1.11 23 fa16.7e7d.7777 A Vlan1"""
file3_content = """Unicast Entries
vlan mac address type protocols port
---------+---------------+--------+---------------------+-------------------------
1 6026.aa11.1111 static ip,ipx,assigned,other Switch
1 0006.f2d2.2d2f dynamic ip,ipx,assigned,other Ethernet1/24
1 6026.aa33.3333 dynamic ip,ipx,assigned,other Ethernet1/12
1 fa16.6edb.6666 dynamic ip,ipx,assigned,other Ethernet1/8
1 fa16.7e7d.7777 dynamic ip,ipx,assigned,other Ethernet1/10"""
# 1. 加载 file1.txt: 只有一列IP地址,无表头
df1 = pd.read_csv(io.StringIO(file1_content), header=None, names=['ipv4'])
print("df1:")
print(df1.head())
print("-" * 30)
# 2. 加载 file2.txt: 多列,以空格分隔,有表头
# 使用 sep=r'\s+' 匹配一个或多个空格作为分隔符,engine='python' 支持正则表达式分隔符
df2 = pd.read_csv(io.StringIO(file2_content), sep=r'\s+', engine='python')
print("df2:")
print(df2.head())
print("-" * 30)
# 3. 加载 file3.txt: 多列,以空格分隔,有表头,但第二行是分隔线需要跳过
# skiprows=[1] 跳过索引为1的行(即第二行)
df3 = pd.read_csv(io.StringIO(file3_content), sep=r'\s+', engine='python', skiprows=[1])
print("df3:")
print(df3.head())
print("-" * 30)说明:
现在我们有了三个DataFrame,接下来就是将它们关联起来。Pandas的merge方法类似于SQL中的JOIN操作,可以根据一个或多个键(列)将两个DataFrame连接起来。
我们将执行两次inner合并:
# 第一次合并:df1 (ipv4) 与 df2 (Address)
# left_on='ipv4' 指明 df1 的连接键是 'ipv4' 列
# right_on='Address' 指明 df2 的连接键是 'Address' 列
# how='inner' 表示只保留两个DataFrame中都存在的匹配项
merged_df_ip_mac = df1.merge(df2, how="inner", left_on="ipv4", right_on="Address")
print("第一次合并结果 (IP-MAC):")
print(merged_df_ip_mac.head())
print("-" * 30)
# 第二次合并:第一次合并的结果 (Addr) 与 df3 (mac address)
# left_on='Addr' 指明 merged_df_ip_mac 的连接键是 'Addr' 列
# right_on='mac address' 指明 df3 的连接键是 'mac address' 列
final_merged_df = merged_df_ip_mac.merge(df3, how="inner", left_on="Addr", right_on="mac address")
print("最终合并结果 (IP-MAC-Port):")
print(final_merged_df.head())
print("-" * 30)经过两次合并,final_merged_df包含了所有我们需要的关联信息。现在,我们只需要选择ipv4、Addr(MAC地址)和port这三列,并按照指定格式打印出来。
# 提取所需列
result_df = final_merged_df[["ipv4", "Addr", "port"]]
# 打印最终结果
print("最终输出:")
for index, row in result_df.iterrows():
# .strip() 用于去除可能存在的额外空格
print(f"ip {row['ipv4']} addr {row['Addr'].strip()} port {row['port'].strip()}")预期输出:
ip 1.1.1.1 addr 6026.aa11.1111 port Switch ip 1.1.1.2 addr 0006.f2d2.2d2f port Ethernet1/24 ip 1.1.1.3 addr 6026.aa33.3333 port Ethernet1/12 ip 1.1.1.6 addr fa16.6edb.6666 port Ethernet1/8 ip 1.1.1.11 addr fa16.7e7d.7777 port Ethernet1/10
import pandas as pd
import io
# 模拟文件内容,实际应用中直接使用文件名
file1_content = """1.1.1.1
1.1.1.2
1.1.1.3
1.1.1.6
1.1.1.11"""
file2_content = """Protocol Address Age (min) Addr Type Interface
Internet 1.1.1.1 5 6026.aa11.1111 A Ethernet1/49
Internet 1.1.1.2 - 0006.f2d2.2d2f A Vlan1
Internet 1.1.1.3 - 6026.aa33.3333 A Vlan1
Internet 1.1.1.4 0 Incomplete A
Internet 1.1.1.5 0 Incomplete A
Internet 1.1.1.6 64 fa16.6edb.6666 A Vlan1
Internet 1.1.1.11 23 fa16.7e7d.7777 A Vlan1"""
file3_content = """Unicast Entries
vlan mac address type protocols port
---------+---------------+--------+---------------------+-------------------------
1 6026.aa11.1111 static ip,ipx,assigned,other Switch
1 0006.f2d2.2d2f dynamic ip,ipx,assigned,other Ethernet1/24
1 6026.aa33.3333 dynamic ip,ipx,assigned,other Ethernet1/12
1 fa16.6edb.6666 dynamic ip,ipx,assigned,other Ethernet1/8
1 fa16.7e7d.7777 dynamic ip,ipx,assigned,other Ethernet1/10"""
# 1. 加载数据到DataFrame
df1 = pd.read_csv(io.StringIO(file1_content), header=None, names=['ipv4'])
df2 = pd.read_csv(io.StringIO(file2_content), sep=r'\s+', engine='python')
df3 = pd.read_csv(io.StringIO(file3_content), sep=r'\s+', engine='python', skiprows=[1])
# 2. 执行DataFrame合并操作
# 第一次合并:根据IP地址关联 df1 和 df2
merged_df_ip_mac = df1.merge(df2, how="inner", left_on="ipv4", right_on="Address")
# 第二次合并:根据MAC地址关联第一次合并结果和 df3
final_merged_df = merged_df_ip_mac.merge(df3, how="inner", left_on="Addr", right_on="mac address")
# 3. 提取所需列并格式化输出
result_df = final_merged_df[["ipv4", "Addr", "port"]]
print("最终输出:")
for index, row in result_df.iterrows():
# 使用 .strip() 清除可能存在的列值前后的空白字符
print(f"ip {row['ipv4']} addr {row['Addr'].strip()} port {row['port'].strip()}")通过本教程,我们学习了如何利用Pandas库高效地解决多文件数据关联问题。将原始数据转换为DataFrame,并巧妙运用merge操作,不仅使代码逻辑清晰、易于维护,而且极大地提高了数据处理的效率。掌握Pandas的这一核心功能,将为你的数据分析和自动化任务带来巨大的便利。
以上就是使用Pandas高效整合多文件数据:IP、MAC与端口关联教程的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号