首页 文章

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

提问于
浏览
0

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

  • 如果csv2在两列中有一个风琴,它会在列表中追加两次 .

  • 如果一行没有任何风琴,它就会忽略它 .

我希望它能做到以下几点:

  • 如果一行有器官,请跳到下一行(每行限制一个器官)

  • 如果没有找到器官,请打印"-"

码:

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','-']

3 回答

  • 2

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

    Code 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
    

    Alternate Take

    在这里,我删除了不优雅的辅助变量并使用了一种更棘手,更模糊但更愉快(对我而言)的方法

    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', '-']
    

    * Edit 似乎 organs 的顺序对你很重要,所以我改变了用于存储从一个集合到一个列表的器官名称的数据结构 .


    Edit #2

    更准确

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

    我想我们想要从左到右扫描每个 line 中的 item 并在找到匹配时停止扫描,到目前为止一直都很好......但是如果 item 匹配多个 organ 怎么办?

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

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

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

    那说,你的选择是......

  • 0

    以下代码通常工作,忽略csv2的 Headers 行:

    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')
    
  • 1

    您只需要遍历数据文件(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, '-'
    

相关问题