2013-05-21 3 views
2

원자 위치를 설명하는 두 세트의 데이터가 있습니다. 그것들은 내가 비교하기를 원하는 별도의 파일에 있습니다. 일치하는 원자를 좌표로 식별하는 것을 목표로합니다. 두 가지 경우 모두 데이터는 다음과 같으며 1000 개 정도의 항목이있을 것입니다.파이썬을 사용하여 두 파일의 좌표 일치 확인

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 
+0

각 개별 파일에서 좌표가 고유하거나 중복 될 수 있습니까? – hexparrot

+0

모든 좌표는 겹치지 않는 개별 원자를 설명하기 때문에 구별되어야합니다. – user2405718

+0

numpy.loadtxt를 사용하고 배열로 모든 것을 처리하십시오 ... –

답변

1

두 목록에있는 각 요소의 두 번째 요소를 비교하기 위해 노력하고있는 모두가 그 각각의 COORD의 비교 각 COORD을 가지고 수행 할 수있는 경우 반대 파일. 이것은 가장 빠른 방법은 아니지만 원하는 결과를 얻을 수 있습니다. 작은 목록을 스캔하여 big_list의 각 항목에 대한 모든 좌표에 대해 모든 small_entry [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]) 

이렇게 하시겠습니까?

+0

위대한 작품입니다 - 많이 감사드립니다! – user2405718

+1

향후이 방법을 다시 사용하려면이 방법이 상당히 비효율적입니다. – hexparrot

+0

작업을 수행 할 수있는 간단한 스크립트가 될 수 있지만 효율성을 향상시키는 가장 좋은 방법은 무엇입니까? – user2405718

2

좌표가 키가되도록 사전을 사용하십시오.

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 

부동 소수점을 비교하는 것이 항상 문제가된다는 점에 유의하십시오.

+0

Working 내 길을 통해서 - 사전을 사용하는 법을 배우고 싶습니다. 건배에 대한 건배! – user2405718

+1

@LutzHornGotcha는 같은 방식으로 coords2를 읽는 것을 오해했습니다. (당신은 단지 목록 이해력이 슬리 팅이라는 것을 의미했습니다) 또한 당신이 그들을 코즈 코드에 넣었다고 가정했습니다. 이전의 코멘트를 취소 함 (어제 이미 upvoted) – UpAndAdam

+0

또한 이것이 @ Tadgh O (n * logn) vs O (n^2)의 대답보다 훨씬 빠릅니다. – UpAndAdam

0

빌드이 사전 다음과 같은 방법 : 여기

# 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])]) 
0

은 사전 사용하는 접근 방식 :

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의 좌표 문자열이 사전 coords 인 경우 두 목록에 쌍이 존재합니다. 그런 다음 일치하는 첫 번째 및 두 번째 목록에서 ID를 인쇄합니다.

사전 조회는 훨씬 빠릅니다 O (1). 이 접근법은 또한 타입 - 캐스팅 (예 : float/int 변환)을 걱정할뿐만 아니라 점검 (하나의리스트)하기 위해 메모리에 모든 데이터를 가질 필요가 없다는 장점이 있습니다.

관련 문제