从以字符串为元素的列表的列表中查找交集

时间:2018-12-19 20:36:52

标签: python pandas list

我有以下列表列表,其中内部列表包含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等。然后我想通过使用它们的坐标来查找Mo0,Mo1,Mo2,Mo3之间是否存在任何共同的S. Mo0的邻居中S的坐标为:

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 :(得分:0)

只需解析字符串,而无需导入任何内容:

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

答案 1 :(得分:0)

您可以使用ast.literal_evalregex清理数据:

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)

您可以通过在样本数据中故意创建重复项来确认此方法是否有效。