0

0

使用Pandas高效整合多文件数据:IP、MAC与端口关联教程

霞舞

霞舞

发布时间:2025-09-21 11:53:00

|

514人浏览过

|

来源于php中文网

原创

使用pandas高效整合多文件数据:ip、mac与端口关联教程

本教程详细演示了如何利用Python的Pandas库高效地从多个文本文件中提取、关联并整合特定数据。通过将文件数据加载为DataFrame,并使用merge操作进行基于IP地址和MAC地址的内连接,最终实现从不同来源的文件中精确匹配并输出IP、MAC地址及对应端口的关联信息。

场景描述与挑战

在日常的数据处理任务中,我们经常会遇到需要从多个分散的文本文件中提取信息,并根据某些共同的标识符将它们关联起来的场景。例如,你可能有一个包含IP地址列表的文件,一个记录IP地址与MAC地址映射关系的文件,以及一个包含MAC地址与交换机端口对应关系的文件。我们的目标是,给定一个IP地址列表,找出每个IP对应的MAC地址,进而找到该MAC地址所连接的交换机端口,并最终输出IP、MAC地址和端口的对应关系。

手动通过文件迭代和字符串匹配来完成这项任务不仅效率低下,而且代码复杂、易出错。当文件规模增大时,这种方法几乎不可行。幸运的是,Python的Pandas库提供了强大的数据结构(DataFrame)和数据操作工具,可以极大地简化此类任务。

Pandas解决方案概览

Pandas库的核心是DataFrame,它是一个二维的、表格型的数据结构,类似于电子表格或SQL数据库中的表。Pandas提供了丰富的函数来读取各种数据源、进行数据清洗、转换、合并以及分析。对于多文件数据关联问题,我们可以将每个文件加载为DataFrame,然后使用merge方法像SQL的JOIN操作一样将它们连接起来。

数据准备:从文件加载到DataFrame

首先,我们需要将提供的三个文本文件(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)

说明:

  • io.StringIO() 用于将字符串内容模拟成文件对象,方便演示。实际应用中,直接将io.StringIO(...)替换为文件路径,如'file1.txt'。
  • header=None:表示文件没有表头,Pandas会默认生成数字列名。
  • names=['ipv4']:为没有表头的文件指定列名。
  • sep=r'\s+':使用正则表达式匹配一个或多个空格作为分隔符,适用于列之间有不规则空格的情况。
  • engine='python':当sep参数使用正则表达式时,需要指定engine='python'。
  • skiprows=[1]:跳过文件的第二行(索引为1的行),因为它是分隔符。

核心操作:DataFrame合并(Merge)

现在我们有了三个DataFrame,接下来就是将它们关联起来。Pandas的merge方法类似于SQL中的JOIN操作,可以根据一个或多个键(列)将两个DataFrame连接起来。

我们将执行两次inner合并:

  1. 第一次合并: 将df1(IP列表)与df2(IP-MAC映射)合并,以df1的ipv4列和df2的Address列作为连接键。这将筛选出file1中存在的IP,并获取它们在file2中对应的MAC地址(Addr列)。
  2. 第二次合并: 将第一次合并的结果与df3(MAC-端口映射)合并,以第一次合并结果的Addr列和df3的mac address列作为连接键。这将获取对应的端口信息。
# 第一次合并: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()}")

注意事项与最佳实践

  1. 文件格式多样性: 实际文件可能比示例更复杂。pd.read_csv提供了大量参数(如delimiter, quotechar, skipinitialspace, na_values等),可以灵活处理各种CSV、TSV或其他分隔符文件。
  2. 合并类型选择 (how参数):
    • inner (默认):只保留两个DataFrame中都存在的匹配项。
    • left:保留左DataFrame的所有行,并匹配右DataFrame的行;如果右DataFrame没有匹配项,则填充NaN。
    • right:保留右DataFrame的所有行,并匹配左DataFrame的行;如果左DataFrame没有匹配项,则填充NaN。
    • outer:保留两个DataFrame的所有行,如果某侧没有匹配项,则填充NaN。 根据你的业务需求选择合适的合并类型。
  3. 性能考量: Pandas的底层是C语言实现的,因此其操作(尤其是merge)在大数据集上比纯Python循环要快得多。对于TB级别的数据,Pandas可能不再是最佳选择,可以考虑Dask或PySpark等分布式计算框架。
  4. 数据清洗: 在合并之前,确保用于连接的列数据类型一致,且没有前导/尾随空格或不一致的大小写。例如,可以使用.str.strip()去除字符串列的空格,使用.str.lower()进行大小写统一。
  5. 列名冲突: 如果两个DataFrame中有相同的列名但不是用于合并的键,Pandas会在合并后自动添加_x和_y后缀来区分它们。可以使用suffixes参数自定义这些后缀。

总结

通过本教程,我们学习了如何利用Pandas库高效地解决多文件数据关联问题。将原始数据转换为DataFrame,并巧妙运用merge操作,不仅使代码逻辑清晰、易于维护,而且极大地提高了数据处理的效率。掌握Pandas的这一核心功能,将为你的数据分析和自动化任务带来巨大的便利。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
C语言变量命名
C语言变量命名

c语言变量名规则是:1、变量名以英文字母开头;2、变量名中的字母是区分大小写的;3、变量名不能是关键字;4、变量名中不能包含空格、标点符号和类型说明符。php中文网还提供c语言变量的相关下载、相关课程等内容,供大家免费下载使用。

401

2023.06.20

c语言入门自学零基础
c语言入门自学零基础

C语言是当代人学习及生活中的必备基础知识,应用十分广泛,本专题为大家c语言入门自学零基础的相关文章,以及相关课程,感兴趣的朋友千万不要错过了。

619

2023.07.25

c语言运算符的优先级顺序
c语言运算符的优先级顺序

c语言运算符的优先级顺序是括号运算符 > 一元运算符 > 算术运算符 > 移位运算符 > 关系运算符 > 位运算符 > 逻辑运算符 > 赋值运算符 > 逗号运算符。本专题为大家提供c语言运算符相关的各种文章、以及下载和课程。

354

2023.08.02

c语言数据结构
c语言数据结构

数据结构是指将数据按照一定的方式组织和存储的方法。它是计算机科学中的重要概念,用来描述和解决实际问题中的数据组织和处理问题。数据结构可以分为线性结构和非线性结构。线性结构包括数组、链表、堆栈和队列等,而非线性结构包括树和图等。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

259

2023.08.09

c语言random函数用法
c语言random函数用法

c语言random函数用法:1、random.random,随机生成(0,1)之间的浮点数;2、random.randint,随机生成在范围之内的整数,两个参数分别表示上限和下限;3、random.randrange,在指定范围内,按指定基数递增的集合中获得一个随机数;4、random.choice,从序列中随机抽选一个数;5、random.shuffle,随机排序。

604

2023.09.05

c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

530

2023.09.20

c语言get函数的用法
c语言get函数的用法

get函数是一个用于从输入流中获取字符的函数。可以从键盘、文件或其他输入设备中读取字符,并将其存储在指定的变量中。本文介绍了get函数的用法以及一些相关的注意事项。希望这篇文章能够帮助你更好地理解和使用get函数 。

645

2023.09.20

c数组初始化的方法
c数组初始化的方法

c语言数组初始化的方法有直接赋值法、不完全初始化法、省略数组长度法和二维数组初始化法。详细介绍:1、直接赋值法,这种方法可以直接将数组的值进行初始化;2、不完全初始化法,。这种方法可以在一定程度上节省内存空间;3、省略数组长度法,这种方法可以让编译器自动计算数组的长度;4、二维数组初始化法等等。

603

2023.09.22

Python 自然语言处理(NLP)基础与实战
Python 自然语言处理(NLP)基础与实战

本专题系统讲解 Python 在自然语言处理(NLP)领域的基础方法与实战应用,涵盖文本预处理(分词、去停用词)、词性标注、命名实体识别、关键词提取、情感分析,以及常用 NLP 库(NLTK、spaCy)的核心用法。通过真实文本案例,帮助学习者掌握 使用 Python 进行文本分析与语言数据处理的完整流程,适用于内容分析、舆情监测与智能文本应用场景。

10

2026.01.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.3万人学习

Django 教程
Django 教程

共28课时 | 3.6万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号