使用python从两个文件中识别坐标匹配
我有两组描述原子位置的数据。它们在不同的文件中,我想比较一下,目的是通过它们的坐标来识别匹配的原子。这两种情况下的数据如下所示,最多会有1000个左右的条目。这些文件的长度不同,因为它们描述了不同大小的系统,并且具有以下格式:使用python从两个文件中识别坐标匹配,python,list,file-io,Python,List,File Io,我有两组描述原子位置的数据。它们在不同的文件中,我想比较一下,目的是通过它们的坐标来识别匹配的原子。这两种情况下的数据如下所示,最多会有1000个左右的条目。这些文件的长度不同,因为它们描述了不同大小的系统,并且具有以下格式: 1 , 0.000000000000E+00 0.000000000000E+00 2 , 0.000000000000E+00 2.468958660000E+00 3 , 0.000000000000E+0
1 , 0.000000000000E+00 0.000000000000E+00
2 , 0.000000000000E+00 2.468958660000E+00
3 , 0.000000000000E+00 -2.468958660000E+00
4 , 2.138180920454E+00 -1.234479330000E+00
5 , 2.138180920454E+00 1.234479330000E+00
第一列是条目ID,第二列是x,y中的一组坐标
我想做的是比较两组数据中的坐标,识别匹配项和相应的ID,例如“文件1中的条目3对应于文件2中的条目6”。我将使用此信息更改文件2中的坐标值
我已经逐行阅读了这些文件,并使用命令将它们分成每行两个条目,然后将它们放入一个列表中,但是对于如何指定比较位,我有点困惑——特别是告诉它只比较第二个条目,同时能够调用第一个条目。我想这需要循环
到目前为止,代码如下所示:
open1 = open('./3x3supercell_coord_clean','r')
openA = open('./6x6supercell_coord_clean','r')
small_list=[]
for line in open1:
stripped_small_line = line.strip()
column_small = stripped_small_line.split(",")
small_list.append(column_small)
big_list=[]
for line in openA:
stripped_big_line = line.strip()
column_big = stripped_big_line.split(",")
big_list.append(column_big)
print small_list[2][1] #prints out coords only
如果您所做的只是尝试比较两个列表中每个元素的第二个元素,那么可以通过将每个坐标与另一个文件中的每个坐标进行比较来实现。这肯定不是最快的方法,但它应该可以得到您需要的结果。它扫描小列表,并对照大列表中每个条目的每个坐标检查每个小条目[1](坐标)
for small_entry in small_list:
for big_entry in big_list:
if small_entry[1] == big_entry[1] :
print(small_entry[0] + "matches" + big_entry[0])
类似这样的东西?使用坐标作为键的字典
data1 = """1 , 0.000000000000E+00 0.000000000000E+00
2 , 0.000000000000E+00 2.468958660000E+00
3 , 0.000000000000E+00 -2.468958660000E+00
4 , 2.138180920454E+00 -1.234479330000E+00
5 , 2.138180920454E+00 1.234479330000E+00"""
# Read data1 into a list of tupes (id, x, y)
coords1 = [(int(line[0]), float(line[2]), float(line[3])) for line in
(line.split() for line in data1.split("\n"))]
# This dictionary will map (x, y) -> id
coordsToIds = {}
# Add coords1 to this dictionary.
for id, x, y in coords1:
coordsToIds[(x, y)] = id
# Read coords2 the same way.
# Left as an exercise to the reader.
# Look up each of coords2 in the dictionary.
for id, x, y in coords2:
if (x, y) in coordsToIds:
print(coordsToIds[(x, y)] # the ID in coords1
请注意,比较浮动总是一个问题。按以下方式构建两个字典:
# do your splitting to populate two dictionaries of this format:
# mydata1[Coordinate] = ID
# i.e.
for line in data1.split():
coord = line[2] + ' ' + line[3]
id = line[0]
mydata1[coord] = id
for line in data2.split():
coord = line[2] + ' ' + line[3]
id = line[0]
mydata2[coord] = id
#then we can use set intersection to find all coordinates in both key sets
set1=set(mydata1.keys())
set2=set(mydata2.keys())
intersect = set1.intersection(set2)
for coordinate in intersect:
print ' '.join(["Coordinate", str(coordinate), "found in set1 id", set1[coordinate]), "and set2 id", set2[coordinate])])
以下是一种使用字典的方法:
coords = {}
with open('first.txt', 'r') as first_list:
for i in first_list:
pair = [j for j in i.split(' ') if j]
coords[','.join(pair[2:4])] = pair[0]
#reformattted coords used as key "2.138180920454E+00,-1.234479330000E+00"
with open('second.txt', 'r') as second_list:
for i in second_list:
pair = [j for j in i.split(' ') if j]
if ','.join(pair[2:4]) in coords:
#reformatted coords from second list checked for presence in keys of dictionary
print coords[','.join(pair[2:4])], pair[0]
这里发生的事情是,文件A中的每个坐标(您已经声明将是不同的)作为键存储到字典中。然后,关闭第一个文件,打开第二个文件。打开第二个列表的坐标,重新格式化以匹配字典键的保存方式,并检查成员资格。如果列表B中的坐标字符串位于dictionarycoords
中,则该对在两个列表中都存在。然后,它打印第一个和第二个列表中与该匹配相关的ID
字典查找比O(1)快得多。这种方法还有一个优点,即不需要将所有数据都存储在内存中以进行检查(仅一个列表),也不必担心类型转换,例如浮点/int转换。在每个单独的文件中,预计坐标是不同的还是会有重复的?所有坐标都应该是不同的,因为它们描述的是单个原子,不会重叠。请,尝试使用numpy.loadtxt并将所有内容作为数组处理……如果您打算在将来重用此方法,这将是非常低效的。它本来是一个简单的脚本,可以完成这项工作,但如何才能最好地提高效率?正如我所说,绝对不是最快的方法。但是,如果你只有几千个条目,它就完成了任务。这当然不是最快的方法——但实际上我正在努力寻找一种比为列表a中的每个条目重新迭代列表B更慢的方法。@hexparrot这是因为这是最慢的方法:-)按照我的方式完成这项工作-还想学习如何使用字典。为不同的拍摄干杯@卢茨霍恩明白了,他以同样的方式误解了阅读合作2的含义;(你只是指列表理解切割)假设你也将它们放入Coordstoid中。收回先前的评论(我昨天已经投票了),并注意到这比@Tadgh O(n*logn)vs O(n^2)接受的答案要快得多