比较两个csv文件以输出匹配的Python



我有一个名为"器官.csv"的csv文件和另一个包含大量数据的csv文件。我正在比较它们以获得它们之间的匹配。后一个文件没有任何特定的格式,所以我不知道哪一列有关于器官的数据。我已经尝试了下面的代码来获取匹配项,但它有两个问题。

  1. 如果 csv2 在两列中有一个器官,它会附加到列表中两次。
  2. 如果一行没有任何器官,它只是忽略它。

我希望它执行以下操作:

    如果一行有管风琴
  1. ,请跳到下一行(每行限制一个管风琴)
  2. 如果未找到器官,请打印类似"-"的内容

法典:

import csv
filename = "file.csv"
complist, orglist = [], []
fileA = open(filename, "rb")
reader = csv.reader(fileA, delimiter=',')
for row in reader:
    for row_str in row:
        complist.append(row_str)
with open("organs.csv", "rb") as fileB:
    reader = csv.reader(fileB, delimiter='n')
    for row in reader:
        orglist += row
        orglist = [x.lower() for x in orglist]
org = open ("organ_matches.txt", "wb")
org_writer = csv.writer(org)
for s in complist:
    for xs in orglist:
        if xs in s:
            print >> org, xs
org.close()
orgfile = open ("organ_matches.txt" , "r")
organ = orgfile.read()
organ = organ.split("n")
organ = ",".join (organ)
organ = organ.split(",")
orgfile.close()
print organ

CSV1:

forearm
leg
abdomen

CSV2:

h1,h2,h3,h4
data1,forearm biopsy,tissue,cell
data2,leg injury,tissue in leg,cell9
data4,data,tissue4,cell6

它现在打印:

['forearm','leg','leg']

期望输出:

['forearm','leg','-']

在这里,我最终使用了一个列表理解*来存储器官名称,接下来,我已经循环了另一个文件的第二行到最后一行,使用 stop 辅助变量一次退出两个循环(这是你没有抓住的一点...

代码 MkI

organs = [line.strip() for line in file('uno.csv')]
matches = []
for line in [line for line in file('due.csv')][1:]:
    stop = 0
    matches.append('-')
    for item in line.split(','):
        if stop : break
        for organ in organs:
            if organ in item:
                matches[-1] = organ
                stop = 1
print matches

交替拍摄

在这里,我删除了不优雅的辅助变量并使用了一个更棘手的变量,更晦涩但更令人愉快(对我来说...)的方法

organs = [line.strip() for line in file('uno.csv')]
matches = []
for line in [line for line in file('due.csv')][1:]:
    match = '-'
    for item in line.split(','):
        if match != '-' : break
        for organ in organs:
            if organ in item:
                match = organ
    matches.append(match)
print matches

输出

['forearm', 'leg', '-']

*编辑 似乎organs的顺序对您很重要,因此我将用于存储器官名称的数据结构从集合更改为列表。


编辑 #2

更精确

从OP中可以清楚地看出,对于每行due.csv,只需要一个匹配。 回想起来,我不清楚的是,如何只选择一场比赛。

我认为我们想从左到右扫描每个line中的item,并在找到匹配项时停止扫描,到目前为止一切顺利......但是,如果一个item匹配多个organ怎么办?

我当前的代码总是在organs上完成for循环,因此附加的匹配项是 uno.csv 中定义的顺序中的最后一个匹配项......

如果请求的匹配是第一个,则必须修改我的代码,将break添加到 for 循环中organs

        for organ in organs:
            if organ in item:
                match = organ
                break

也就是说,选择权在你...

以下代码通常有效,忽略 csv2 的标题行:

import csv
orglist = []
organ_matches = []
# Generate list of organs
with open('organs.csv', 'rb') as f_org:
    csv_f = csv.reader(f_org)
    for row in csv_f:
        orglist.append(row[0])
# Convert to a set
set_org = set(orglist)
# Read csv2 file
with open('file.csv', 'rb') as f_tbl:
    # Open output file to write to
    with open('organ_matches.txt', 'wb') as f_out:
        csv_f = csv.reader(f_tbl)
        csv_f.next() # Ignore header
        for row in csv_f:
            set_row = set(' '.join(row).split(' ')) # Combine list elements and separate words
            # Find common words with organs list and select only one
            if set_row.intersection(set_org):
                organ_match = list(set_row.intersection(set_org))[0]
            else:
                organ_match = '-'
            organ_matches.append(organ_match)
            f_out.write(organ_match + 'n')

你只需要遍历一次数据文件(complist),就可以删除多余的嵌套循环。

以便您的:

for s in complist:
    for xs in orglist:
        if xs in s:
            print >> org, xs

成为:

for s in complist:
    if s in orglist:
        print >> org, s
    else:
        print >> org, '-'

相关内容

  • 没有找到相关文章

最新更新