我想在序言中说我非常喜欢初学者。
我有两个txt文件。在两列(i,j)中具有约1000个值的一个,指的是已经破碎的成对颗粒。第二个文件包含所有4M粒子列中的XYZ坐标,其中粒子标记(i或j)是行号。我需要从文件1中取出标签(i和j)并找到它们关联的XYZ坐标,以便我得到一个具有以下格式的新文件:
输出: Xi Yi Zi Xj Yj Zj
每个破碎的粒子对。
我不确定使用它的最佳工具是什么。我有一些awk和bash以及python的经验,但我没有到达任何地方。
文件1:
C6i C7j
2084974 2135208
380134 632561
416969 416972
86296 86300
2296040 2343415
493401 562376
444984 522708
405188 536773
84709 130065
文件2:XYZ分别是第3,4和5列。
ni -0.139703912516E-01 -0.588106472470E-02 -0.246993537185E-01 0.240235100000E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
al -0.137235866800E-01 -0.641882704213E-02 -0.251673100913E-01 0.534478800000E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
ni -0.185856021576E-01 -0.152366221623E-01 -0.121702424186E-01 0.243473343750E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
ni -0.189394000761E-01 -0.152668306704E-01 -0.124951222187E-01 0.247782468750E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
ni -0.186657676593E-01 -0.149796823498E-01 -0.117824363740E-01 0.245485618750E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
ni -0.183548072309E-01 -0.146581691495E-01 -0.119760428210E-01 0.262177487500E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
al -0.179781075366E-01 -0.152651341795E-01 -0.118226752981E-01 0.476129550000E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
al -0.184341198964E-01 -0.147587453602E-01 -0.127106194529E-01 0.509758600000E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
ni -0.162533369485E-01 -0.349146188426E-01 -0.141615273706E-01 0.253299731250E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
ni -0.163557464187E-01 -0.344963153936E-01 -0.143620570810E-01 0.239937831250E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
ni -0.166373601765E-01 -0.351914412333E-01 -0.135853527002E-01 0.244891000000E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
al -0.158054048322E-01 -0.352289094572E-01 -0.137329142337E-01 0.462249725000E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
ni -0.405319274446E-01 -0.296567975721E-01 -0.243386549644E-01 0.254679675000E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
ni -0.409494727711E-01 -0.296234747969E-01 -0.240603258346E-01 0.250886643750E-03 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00 0.0000E+00
答案 0 :(得分:2)
使用awk
:
awk 'FNR==NR {xyz[FNR]=$3" "$4" "$5;next;} {print xyz[$1],xyz[$2];}' file2 file
假设file1为:
C6i C7j
2 3
6 1
和file2
与您的问题相同,然后:
$ awk 'FNR==NR {xyz[FNR]=$3" "$4" "$5;next;} {print xyz[$1],xyz[$2];}' file2 file1
-0.641882704213E-02 -0.251673100913E-01 0.534478800000E-03 -0.152366221623E-01 -0.121702424186E-01 0.243473343750E-03
-0.146581691495E-01 -0.119760428210E-01 0.262177487500E-03 -0.588106472470E-02 -0.246993537185E-01 0.240235100000E-03
工作原理:
awk
命令按此顺序给出了两个文件:file2
file1
。 awk
隐式循环遍历文件的每一行。
FNR==NR {xyz[FNR]=$3" "$4" "$5;next;}
FNR是到目前为止从当前文件读取的行数,NR是到目前为止从所有文件读取的行总数。因此,当FNR==NR
时,这意味着我们正在读取命令行中列出的第一个文件。对于该文件,我们将列3,4,5保存到由其行号索引的数组xyz
中。
next
命令告诉awk
跳过剩余的命令并跳转到下一行重新开始。
print xyz[$1],xyz[$2]
如果我们到达此处,我们正在处理第二个命名文件file1
。我们查找数组xyz
中此行上命名的两个粒子的坐标并将其打印出来。
答案 1 :(得分:1)
您可以使用product
中的itertools
以及一些列表操作
from itertools import product
raw_data1 = open('data1.txt').read()
"""
data1.txt holds:
1 2
2 3
"""
raw_data2 = """
a b c d
e f g h
i j k l
"""
data1 = [map(int, x.split()) for x in filter(None, raw_data1.splitlines())]
data2 = [x.split() for x in filter(None, raw_data2.splitlines())]
take_coloumns = lambda x: (x[1], x[2], x[3])
for x, y in data1:
print [take_coloumns(list(product([x], data2[x-1]))),
take_coloumns(list(product([y], data2[y-1])))]
data2[y-1]
是因为python是零索引的,我想你的行是1索引的。代码将输出:
[((1, 'b'), (1, 'c'), (1, 'd')), ((2, 'f'), (2, 'g'), (2, 'h'))]
[((2, 'f'), (2, 'g'), (2, 'h')), ((3, 'j'), (3, 'k'), (3, 'l'))]
你看到了这个想法?如果你有大量的数据,你应该使用动态编程来记住线性的核心化。
答案 2 :(得分:0)
这是bash的尝试,而不是我害怕的最佳解决方案, Python 或 C (甚至 awk ??)应该更适合这份工作
描述:
input file1,col 6 is col 7是j?
输入file2,我们需要col 3,4,5?
因为file2中有400万行,所以无法以方便的方式在bash中使用数组。
这会很慢,所以如果你将file2复制到RAM(无论是作为tmpfs安装的是什么)都是最好的
#!/bin/bash
while read c1 c2 c3 c4 c5 i j
do
sed -n "^$i""p" file2| { read c1 c2 X Y Z ; echo -n "$X $Y $Z ";}
sed -n "^$j""p" file2| { read c1 c2 X Y Z ; echo "$X $Y $Z" ;}
done <file1 >output_file