csv 比较排除了 python 中的重复项

The csv comparison is excluding duplicates in python

我有两个 csv 文件,我正在使用一个 csv 从另一个 csv 搜索所有记录并更新其状态。 我有两个 table 并通过 input.csv 中的搜索 table 寻找 IP 和协议。如果存在,则 EXISTS 列更新为 'No'。 我被困在两个或多个记录的协议和 ip 相同的地方,但它们有不同的端口。它只更新了一条记录。

import csv

IP, EXISTS, PROTOCOL = 'IP', 'Exists', 'Protocol'  # Field names referenced.

# Read entire input file into a list.
with open('input.csv', 'r', newline='') as inp:
    reader = csv.DictReader(inp)
    inputs = list(reader)

# Update input rows that match data in search.csv file.
with open('search.csv', 'r', newline='') as sea:
    sea_reader = csv.DictReader(sea)
    for row in sea_reader:
        protocol, ip = row[PROTOCOL], row[IP]
        for input_ in inputs:
            if input_[PROTOCOL] == protocol and input_[IP] == ip:  # Match?
                input_[EXISTS] = 'No'
                break

# Write updated input.csv data out into a file.
with open('input_updated.csv', 'w', newline='') as outp:
    fieldnames = inputs[0]
    writer = csv.DictWriter(outp, fieldnames)
    writer.writeheader()
    for input_ in inputs:
        writer.writerow(input_)

print('done')

Input.csv

Name IP Protocol Port Exists
l1 192.132.16.02 HTTP 80
l2 192.132.16.03 SSL 8443
l3 192.132.16.03 SSL 443
l4 192.132.16.04 SSL 443

search.csv

No Protocol IP Port
1 HTTP 192.132.16.02 80
2 SSL 192.132.16.03 443
3 SSL 192.132.16.03 8443

这里search.csv有两条协议和ip相同但端口不同的记录。结果它只包括一个记录而不是两个。我也尝试在条件下添加端口,但它不起作用

您可以使用pandas读取csv文件。 为两个文件的两个 IP、协议创建索引。 如果在 input_df 中找到 search_df 的索引,则迭代 search_df 并将值作为 True 插入 Exists 列。重置索引并删除 nan 值。


import pandas as pd
input_df = pd.read_csv("input.csv")
search_df = pd.read_csv("search.csv")
input_df = input_df.set_index(["IP","Protocol"])
search_df = search_df.set_index(["IP","Protocol"])
for index, _ in search_df.iterrows():
    input_df.loc[index,"Exists"] = True
input_df = input_df.reset_index()
input_df = input_df.dropna()

您的代码中唯一的问题是您 break 在找到匹配项后立即退出循环,因此您将永远找不到更多的匹配项。删除 break 将使它工作,当然它会更慢。

有一件事我不清楚:端口号是否相关?在您的示例中,即使第三个搜索行不存在,第二个输入行也会匹配。所以在匹配测试中包含端口号可能是个好主意:

with open('search.csv', 'r', newline='') as sea:
    sea_reader = csv.DictReader(sea)
    for row in sea_reader:
        protocol, ip, port = row[PROTOCOL], row[IP], row[PORT]
        for input_ in inputs:
            if input_[PROTOCOL] == protocol and input_[IP] == ip and input_[PORT] == port:  # Match?
                input_[EXISTS] = 'No'
                break

在这种情况下,break 可以保留,因为您将只有完全匹配(即输入 #2 与搜索 #3 以及输入 #3 与搜索 #2)