比较两个 csv 文件以输出匹配项 Python
Compare two csv files to ouput the matches Python
我有一个名为 "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','-']
您只需要循环遍历您的数据文件 (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, '-'
在这里我最终使用列表理解 *
来存储器官名称,
接下来我遍历了另一个文件的第二行到最后一行,
使用 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', '-']
*
Edit 看来organs
的顺序对你很重要,所以我改变了用来存储名字的数据结构器官从一组到列表。
编辑#2
更准确
从 OP 可以清楚地看出,对于 due.csv
的每一行,只需要一个匹配项。我不清楚(回想起来)是如何只选择一场比赛。
我认为我们想要从左到右扫描每个 line
中的 item
并在找到匹配项时停止扫描,到目前为止一切顺利......但是如果一个item
匹配多个 organ
?
我当前的代码总是在 organs
上完成 for
循环,因此附加的匹配项是 uno.csv
...[=29 中定义的顺序中的最后一个匹配项=]
如果请求的匹配项是第一个,则必须修改我的代码,在 organs
上的 for
循环中添加 break
for organ in organs:
if organ in item:
match = organ
break
也就是说,选择权在你...
以下代码可以正常工作,忽略 csv2 的 header 行:
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')
我有一个名为 "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','-']
您只需要循环遍历您的数据文件 (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, '-'
在这里我最终使用列表理解 *
来存储器官名称,
接下来我遍历了另一个文件的第二行到最后一行,
使用 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', '-']
*
Edit 看来organs
的顺序对你很重要,所以我改变了用来存储名字的数据结构器官从一组到列表。
编辑#2
更准确
从 OP 可以清楚地看出,对于 due.csv
的每一行,只需要一个匹配项。我不清楚(回想起来)是如何只选择一场比赛。
我认为我们想要从左到右扫描每个 line
中的 item
并在找到匹配项时停止扫描,到目前为止一切顺利......但是如果一个item
匹配多个 organ
?
我当前的代码总是在 organs
上完成 for
循环,因此附加的匹配项是 uno.csv
...[=29 中定义的顺序中的最后一个匹配项=]
如果请求的匹配项是第一个,则必须修改我的代码,在 organs
for
循环中添加 break
for organ in organs:
if organ in item:
match = organ
break
也就是说,选择权在你...
以下代码可以正常工作,忽略 csv2 的 header 行:
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')