Нахождение пересечения из списка списка, который имеет строку в качестве элемента - PullRequest
0 голосов
/ 19 декабря 2018

У меня есть следующий список списка, в котором во внутреннем списке есть 2 элемента в строковом формате.

neighbor_list = [['Mo0',
  '[PeriodicSite: S (1.5952, -0.9210, 37.6032) [0.3333, -0.3333, 0.9458], PeriodicSite: S (0.0000, 1.8419, 37.6032) [0.3333, 0.6667, 0.9458], PeriodicSite: S (3.1903, 1.8419, 37.6032) [1.3333, 0.6667, 0.9458], PeriodicSite: S (1.5952, -0.9210, 34.4734) [0.3333, -0.3333, 0.8671], PeriodicSite: S (0.0000, 1.8419, 34.4734) [0.3333, 0.6667, 0.8671], PeriodicSite: S (3.1903, 1.8419, 34.4734) [1.3333, 0.6667, 0.8671]]'],
 ['Mo1',
  '[PeriodicSite: S (1.5952, -0.9210, 12.7242) [0.3333, -0.3333, 0.3200], PeriodicSite: S (0.0000, 1.8419, 12.7242) [0.3333, 0.6667, 0.3200], PeriodicSite: S (3.1903, 1.8419, 12.7242) [1.3333, 0.6667, 0.3200], PeriodicSite: S (1.5952, -0.9210, 9.5944) [0.3333, -0.3333, 0.2413], PeriodicSite: S (0.0000, 1.8419, 9.5944) [0.3333, 0.6667, 0.2413], PeriodicSite: S (3.1903, 1.8419, 9.5944) [1.3333, 0.6667, 0.2413]]'],
 ['Mo2',
  '[PeriodicSite: S (-1.5952, 0.9210, 30.1636) [-0.3333, 0.3333, 0.7587], PeriodicSite: S (1.5952, 0.9210, 30.1636) [0.6667, 0.3333, 0.7587], PeriodicSite: S (0.0000, 3.6839, 30.1636) [0.6667, 1.3333, 0.7587], PeriodicSite: S (-1.5952, 0.9210, 27.0339) [-0.3333, 0.3333, 0.6800], PeriodicSite: S (1.5952, 0.9210, 27.0339) [0.6667, 0.3333, 0.6800], PeriodicSite: S (0.0000, 3.6839, 27.0339) [0.6667, 1.3333, 0.6800]]'],
 ['Mo3',
  '[PeriodicSite: S (-1.5952, 0.9210, 5.2846) [-0.3333, 0.3333, 0.1329], PeriodicSite: S (1.5952, 0.9210, 5.2846) [0.6667, 0.3333, 0.1329], PeriodicSite: S (0.0000, 3.6839, 5.2846) [0.6667, 1.3333, 0.1329], PeriodicSite: S (-1.5952, 0.9210, 2.1548) [-0.3333, 0.3333, 0.0542], PeriodicSite: S (1.5952, 0.9210, 2.1548) [0.6667, 0.3333, 0.0542], PeriodicSite: S (0.0000, 3.6839, 2.1548) [0.6667, 1.3333, 0.0542]]']]

Первым элементом во внутреннем списке (скажем, Mo0) является центр и все Sво втором пункте находятся окрестности.Сначала я хочу напечатать список центральных атомов, добавленных к окружению, например, Mo0S6, Mo1S6, M02S6 и так далее.Затем я хочу выяснить, существуют ли какие-либо общие S между Mo0, Mo1, Mo2, Mo3, используя их координаты, например, координаты для S в соседнем с Mo0:

S (1.5952, -0.9210, 37.6032) 
S (1.5952, -0.9210, 12.7242) 

и т. Д.

Я могу получить центр и окружение, выполнив

for i in range(len(neighbor_list)):
    center = neighbor_list[i][0]
    surroundings = neighbor_list[i][1] 

Как мне суммировать количество окружений для каждого центрального атома и найти пересечение между окружением?

Конечная цельчтобы получить матрицу в следующем формате

      Mo0S6  Mo1S6  Mo2S6  Mo3S6
Mo0S6    0.0    0.0    0.0    0.0
Mo1S6    0.0    0.0    0.0    0.0
Mo2S6    0.0    0.0    0.0    0.0
Mo3S6    0.0    0.0    0.0    0.0

Все элементы в кадре данных равны 0, потому что в этом списке нет общих символов S.

Может кто-нибудь помочь мне в этом.Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Вы можете очистить ваши данные, используя ast.literal_eval и regex:

import pandas as pd
import re, ast

surrounding = [[ast.literal_eval(i) for i in re.findall(r'\([ ,.\d-]+\)', i[1])] for i in neighbor_list]
centers = ['{0}S{1}'.format(i[0], len(s)) for i, s in zip(neighbor_list, surrounding)]

data = dict(zip(centers, surrounding))

Дает:

{'Mo0S6': [(1.5952, -0.921, 37.6032), (0.0, 1.8419, 37.6032), (3.1903, 1.8419, 37.6032), (1.5952, -0.921, 34.4734), (0.0, 1.8419, 34.4734), (3.1903, 1.8419, 34.4734)],
'Mo1S6': [(1.5952, -0.921, 12.7242), (0.0, 1.8419, 12.7242), (3.1903, 1.8419, 12.7242), (1.5952, -0.921, 9.5944), (0.0, 1.8419, 9.5944), (3.1903, 1.8419, 9.5944)],
'Mo2S6': [(-1.5952, 0.921, 30.1636), (1.5952, 0.921, 30.1636), (0.0, 3.6839, 30.1636), (-1.5952, 0.921, 27.0339), (1.5952, 0.921, 27.0339), (0.0, 3.6839, 27.0339)],
'Mo3S6': [(-1.5952, 0.921, 5.2846), (1.5952, 0.921, 5.2846), (0.0, 3.6839, 5.2846), (-1.5952, 0.921, 2.1548), (1.5952, 0.921, 2.1548), (0.0, 3.6839, 2.1548)]}

Затем вы можете сгенерировать фрейм данных напрямую, используя df = pd.Dataframe(data):

                       Mo0S6                      Mo1S6  \
0  (1.5952, -0.921, 37.6032)  (1.5952, -0.921, 12.7242)   
1     (0.0, 1.8419, 37.6032)     (0.0, 1.8419, 12.7242)   
2  (3.1903, 1.8419, 37.6032)  (3.1903, 1.8419, 12.7242)   
3  (1.5952, -0.921, 34.4734)   (1.5952, -0.921, 9.5944)   
4     (0.0, 1.8419, 34.4734)      (0.0, 1.8419, 9.5944)   
5  (3.1903, 1.8419, 34.4734)   (3.1903, 1.8419, 9.5944)   

                       Mo2S6                     Mo3S6  
0  (-1.5952, 0.921, 30.1636)  (-1.5952, 0.921, 5.2846)  
1   (1.5952, 0.921, 30.1636)   (1.5952, 0.921, 5.2846)  
2     (0.0, 3.6839, 30.1636)     (0.0, 3.6839, 5.2846)  
3  (-1.5952, 0.921, 27.0339)  (-1.5952, 0.921, 2.1548)  
4   (1.5952, 0.921, 27.0339)   (1.5952, 0.921, 2.1548)  
5     (0.0, 3.6839, 27.0339)     (0.0, 3.6839, 2.1548) 

Чтобы найти дубликаты, мы можем просто использовать stack() и duplicated(keep=False), где keep=False гарантирует, что мы возвращаем как дубликаты, так и связанные с ними центры:

df.stack()[df.stack().duplicated(keep=False)]

Выход:

Series([], dtype: object)

Вы можете подтвердить, что этот метод работает, преднамеренно создавая дубликат в данных образца.

0 голосов
/ 19 декабря 2018

Просто разбор строк без необходимости что-либо импортировать:

for item in neighbor_list:
    center=item[0]
    surroundings=item[1].split("PeriodicSite: S ")

    # remove extra brackets
    surroundings=surroundings[1:]
    surroundings[-1]=surroundings[-1][0:-1]

    print "%sS%d" % (center, len(surroundings))

    surroundings = [x.replace("("," ").replace(")"," ").replace("["," ").replace("]"," ").replace(","," ") for x in surroundings]
    surroundings = [x.split() for x in surroundings]

    for S in surroundings:
        print "S (%s,%s,%s)" % (S[0], S[1], S[2])

Дает:

Mo0S6
S (1.5952,-0.9210,37.6032)
S (0.0000,1.8419,37.6032)
S (3.1903,1.8419,37.6032)
S (1.5952,-0.9210,34.4734)
S (0.0000,1.8419,34.4734)
S (3.1903,1.8419,34.4734)
Mo1S6
S (1.5952,-0.9210,12.7242)
S (0.0000,1.8419,12.7242)
S (3.1903,1.8419,12.7242)
S (1.5952,-0.9210,9.5944)
S (0.0000,1.8419,9.5944)
S (3.1903,1.8419,9.5944)
Mo2S6
S (-1.5952,0.9210,30.1636)
S (1.5952,0.9210,30.1636)
S (0.0000,3.6839,30.1636)
S (-1.5952,0.9210,27.0339)
S (1.5952,0.9210,27.0339)
S (0.0000,3.6839,27.0339)
Mo3S6
S (-1.5952,0.9210,5.2846)
S (1.5952,0.9210,5.2846)
S (0.0000,3.6839,5.2846)
S (-1.5952,0.9210,2.1548)
S (1.5952,0.9210,2.1548)
S (0.0000,3.6839,2.1548
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...