我有两个包含数千个条目的大型csv文件,每个文件包含以下形式的两列ID:
BRADI5G01462.1_1 NCRNA_34654_1853
BRADI5G01462.1_1 NCRNA_34398_1942
BRADI5G01462.1_1 NCRNA_2871_1959
我已经尝试了这个,但它没有给出预期的结果:
import csv
files=["#Left(Brachypodium_Japonica).csv","#Right(Brachypodium_Japonica).csv"]
for i in range(len(files)):
name=files[i][files[i].find("#")+1:files[i].find(".")]
with open(files[i],"r",newline='') as source:
rdr= csv.reader( source,delimiter="\t",skipinitialspace=True )
with open("@"+name+".csv","w",newline='') as result:
wtr= csv.writer( result,delimiter="\t",skipinitialspace=True )
for r in rdr:
wtr.writerow( (r[1],r[2]) )
l1 = set(open('@Left(Brachypodium_Japonica).csv'))
l2 = set(open('@Right(Brachypodium_Japonica).csv'))
open('Intersection(Brachypodium_Japonica).csv', 'w').writelines(l1 & l2)
找到两个文件之间交集的最有效的pythonic方法是什么?!通过它,即两个文件中两列的整个匹配。
我已经问过这个问题before,但没有人费心去帮忙。
我真的陷入了困境,迫切需要得到高度赞赏的帮助。
修改
文件1(左)输入样本:
BRADI5G16060.1_36 OS08T0547100-02_5715
BRADI3G00440.1_243 OS03T0274400-01_2650
BRADI3G58610.1_438 OS01T0112500-01_899
BRADI1G73670.1_850 OS11T0481500-01_6621
BRADI1G78150.1_870 OS02T0543300-00_2055
文件2(右)输入样本:
BRADI5G16060.1_36 OS08T0547100-02_5715
BRADI4G45180.1_240 OS03T0103800-01_2473
BRADI2G12470.2_487 OS04T0470600-00_3504
BRADI1G73670.1_850 OS11T0481500-01_6621
BRADI1G78330.1_878 OS06T0155600-01_4411
Left&的交叉文件右:
BRADI5G16060.1_36 OS08T0547100-02_5715
BRADI1G73670.1_850 OS11T0481500-01_6621
答案 0 :(得分:0)
当我查看您的代码时,它看起来像这样,
- >您有两个文件
- >您将它们再次写入两个文件
- >最后将它们添加到交叉点文件
让我们删除第二步
import csv
files=["#Left(Brachypodium_Japonica).csv","#Right(Brachypodium_Japonica).csv"]
for i in files:
with open(i,"r",newline='') as source:
rdr= csv.reader( source,delimiter="\t",skipinitialspace=True )
with open('Intersection(Brachypodium_Japonica).csv',"aw",newline='') as result:
wtr= csv.writer( result,delimiter="\t",skipinitialspace=True )
for r in rdr:
wtr.writerow( (r[0],r[1]) )
步骤:
- >读取第一个文件并将其添加到交叉点
- >阅读下一个文件并继续追加
尝试这个,如果不起作用,请告诉我。 我不知道你为什么使用那个换行符跳过但是如果你知道为什么,那么你可以继续使用它。 我按照你的格式以适当的方式重写了代码。
我在我的系统上尝试过,如果它不起作用,它会起作用指出追溯或错误。
答案 1 :(得分:0)
以下脚本读取两个(或更多)CSV文件,并将行条目的交集写入新的CSV文件。我的意思是,如果在input1.csv
中的任何位置找到input2.csv
中的row1,则该行将被写入输出,依此类推。
import csv
files = ["input1.csv", "input2.csv"]
ldata = []
for file in files:
with open(file, "r") as f_input:
csv_input = csv.reader(f_input, delimiter="\t", skipinitialspace=True)
set_rows = set()
for row in csv_input:
set_rows.add(tuple(row))
ldata.append(set_rows)
with open("Intersection(Brachypodium_Japonica).csv", "wb") as f_output:
csv_output = csv.writer(f_output, delimiter="\t", skipinitialspace=True)
csv_output.writerows(set.intersection(*ldata))
您需要添加文件名mangling。这种格式使测试更容易。使用Python 2.7进行测试。
答案 2 :(得分:0)
这里我做了一些假设,如果错误,代码会更复杂:
\t
)
import mmap
indexes = {}
left_fp = open('left.csv', 'r')
left = mmap.mmap(left_fp.fileno(), 0, access=mmap.ACCESS_READ)
while True:
start = left.tell()
line = left.readline()
if not line: break
# extract only the two columns you check
cells = line.split('\t')[0:2]
# store line position in left file
indexes['\t'.join(cells)] = (start, left.tell() - start)
output = open('output.csv', 'w')
for line in open('right.csv'):
# recreate the key
cells = line.split('\t')[0:2]
pos = left_indexes[key]
if pos:
# got the left line position
left.seek(pos[0], 0)
# write it
output.write(left.read(pos[1]))
# write right row
output.write(line)
output.close()
答案 3 :(得分:0)
我有一个类似的问题,我需要找到两个相当大的CSV文件(74M行与450M行)的交集。基本思想是读取较小的文件并建立一个查找表,该表可在遍历较大的文件时使用。
我发现最快的方法是使用jq
命令行工具。
smaller.csv :
BRADI5G16060.1_36 OS08T0547100-02_5715
BRADI3G00440.1_243 OS03T0274400-01_2650
BRADI3G58610.1_438 OS01T0112500-01_899
BRADI1G73670.1_850 OS11T0481500-01_6621
BRADI1G78150.1_870 OS02T0543300-00_2055
larger.csv :
BRADI5G16060.1_36 OS08T0547100-02_5715
BRADI3G00440.1_243 OS03T0274400-01_2650
BRADI3G58610.1_438 OS01T0112500-01_899
BRADI1G73670.1_850 OS11T0481500-01_6621
BRADI1G78150.1_870 OS02T0543300-00_2055
...
以json字典的形式准备 smaller.csv 的查找表,并将其写入 smaller.json :
$ jq -s -R 'split("\n")|map({key:.,value:1})|from_entries' smaller.csv | tee smaller.json
{
"BRADI5G16060.1_36 OS08T0547100-02_5715": 1,
"BRADI3G00440.1_243 OS03T0274400-01_2650": 1,
"BRADI3G58610.1_438 OS01T0112500-01_899": 1,
"BRADI1G73670.1_850 OS11T0481500-01_6621": 1,
"BRADI1G78150.1_870 OS02T0543300-00_2055": 1
}
现在迭代 larger.csv 并使用 smaller.json 作为查找表进行过滤:
$ jq -R -r --slurpfile F smaller.json 'select($F[0][.])' larger.csv | tee intersection.csv
BRADI5G16060.1_36 OS08T0547100-02_5715
BRADI1G73670.1_850 OS11T0481500-01_6621