首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >比较两个csv文件以输出匹配的Python

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

Stack Overflow用户
提问于 2015-01-16 19:56:20
回答 3查看 2K关注 0票数 1

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

  1. 如果csv2在两列中有一个器官,它会在列表中追加两次。
  2. 如果一排没有任何器官,它就会忽略它。

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

  1. 如果一行有一个器官,跳到下一个器官(限制每一行一个器官)
  2. 如果没有找到器官,打印"-“

代码:

代码语言:javascript
复制
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:

代码语言:javascript
复制
forearm
leg
abdomen

csv2:

代码语言:javascript
复制
h1,h2,h3,h4
data1,forearm biopsy,tissue,cell
data2,leg injury,tissue in leg,cell9
data4,data,tissue4,cell6

它现在打印:

代码语言:javascript
复制
['forearm','leg','leg']

期望产出:

代码语言:javascript
复制
['forearm','leg','-']
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-01-16 20:33:52

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

代码MkI

代码语言:javascript
复制
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

交替取

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

代码语言:javascript
复制
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

输出量

代码语言:javascript
复制
['forearm', 'leg', '-']

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

编辑#2

更准确地说

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

我认为我们想从左到右扫描每个line中的line,当我们找到匹配时停止扫描,到目前为止还不错.但是如果一个item与多个organ匹配呢?

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

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

代码语言:javascript
复制
        for organ in organs:
            if organ in item:
                match = organ
                break

尽管如此,选择是你的..。

票数 2
EN

Stack Overflow用户

发布于 2015-01-16 20:54:13

以下代码通常可以工作,忽略csv2的标题行:

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2015-01-16 20:07:21

您只需要循环一次您的数据文件(编译器),并可以删除额外的嵌套循环。

所以你的:

代码语言:javascript
复制
for s in complist:
    for xs in orglist:
        if xs in s:
            print >> org, xs

变成:

代码语言:javascript
复制
for s in complist:
    if s in orglist:
        print >> org, s
    else:
        print >> org, '-'

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27991814

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档