如何解决在Python中,如何根据一个列中的值比较两个csv文件,并从第一个文件输出与第二个不匹配的记录
对于python和编码来说是相当新的。我一直在寻找一些csv比较问题和答案,却找不到任何有助于解决此特定比较问题的东西。
我有两个包含网络资产信息的文件。某些设备在一个文件中有多个IP地址,而在另一个文件中只有一个地址。而且它们似乎不共享大写或小写格式。我对他们的主机名值感兴趣。
(文件没有标题)
文件1:
HOSTNAME1,10.0.0.1
HOSTNAME2,10.0.0.2
HOSTNAME3,10.19.0.3
hostname4,10.19.0.4,10.19.17.31,10.19.17.32,10.19.17.33,10.19.17.34
hostname5,10.19.0.40,10.19.17.51,10.19.17.52,10.19.17.53,10.19.17.54
hostname6,10.19.0.55,10.19.17.56,10.19.17.57,10.19.17.58,10.19.17.59
文件2
HOSTNAME4,10.19.0.4
HOSTNAME5,10.19.0.40
HOSTNAME6,10.19.0.55
hostname7,192.168.0.1
hostname8,192.168.0.2
hostname9,192.168.0.3
我想根据主机名(第0列)比较这些文件,并输出到包含file1中不在file2中的行的第三个文件,忽略大小写,并忽略它们在file1或file2中是否具有多个IP
所需的输出:
文件3:
HOSTNAME1,10.19.0.3
我在bash中尝试了一个简单的comm命令,以查看是否可以生成所需的结果并且没有运气,所以我决定在python中尝试
comm -23 --nocheck-order file1.csv file2.csv > file3.csv
这是我在python中尝试过的内容:
with open('file1.csv','r') as f1,open('file2.csv','r') as f2:
fileone = f1.readlines()
filetwo = f2.readlines()
with open('file3.csv','w') as outFile:
for line in fileone:
if line not in filetwo:
outFile.write(line)
问题是它没有写IP列表不完全匹配的行。即使在第1列中它们共享一个主机名,如果该行在一个文件中有多个ip,也不会计算在内。
我不确定我上面的代码是否忽略大小写,并且似乎是试图从一行中匹配整个字符串,而不是“包含”。
愿意尝试使用pandas软件包,如果这种比较更有意义
解决方法
您自己的代码离您要做的事情不太远。
步骤1::从file2.csv
中的主机名列表中创建一个集合。在这里,主机名更改为大写。
with open('file2.csv') as check_file:
check_set = set([row.split(',')[0].strip().upper() for row in check_file])
步骤2:遍历file1.csv
行,并检查主机名是否在集合中。
with open('file1.csv','r') as in_file,open('file3.csv','w') as out_file:
for line in in_file:
if line.split(',')[0].strip().upper() not in check_set:
out_file.write(line)
生成的文件file3.csv
的内容:
HOSTNAME1,10.0.0.1
HOSTNAME2,10.0.0.2
HOSTNAME3,10.19.0.3
,
由于您有兴趣使用Pandas
,因此建议您这样做。
使用read_csv
读取csv文件,并使用merge
合并两者并识别不匹配的内容。但是为此,两个文件中的列数应该相同(或使用names
来定义列)。话虽如此,如果您只对第一列比较满意,可以尝试一下。
import pandas as pd
#Read the 2 csv files and take only the first column
file1_df = pd.read_csv('filename1.csv',usecols=[0],names=['Name'])
file2_df = pd.read_csv('filename2.csv',names=['Name'])
#Converting both the files first column to uppercase to make it case insensitive
file1_df['Name'] = file1_df['Name'].str.upper()
file2_df['Name'] = file2_df['Name'].str.upper()
#Merging both the Dataframe using left join
comparison_result = pd.merge(file1_df,file2_df,on='Name',how='left',indicator=True)
#Filtering only the rows that are available in left(file1)
comparison_result = comparison_result.loc[comparison_result['_merge'] == 'left_only']
print(comparison_result)
正如我所告诉的,由于两个csv中的列数是不同的(如果用逗号分隔),所以我只读取第一列。因此,输出也将只有一列,如下所示。
HOSTNAME1
HOSTNAME2
HOSTNAME3
,
您只需要比较第一列,请尝试如下操作
filetwo=[val.split(',')[0].strip().lower() for val in filetwo]
for line in fileone:
if line.split(',')[0].strip().lower() not in filetwo:
print(line)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。