【问题标题】:How can I check whether every second value from a dictionary is in a specific range?如何检查字典中的每一秒值是否在特定范围内?
【发布时间】:2017-12-31 20:17:11
【问题描述】:

我有一本从名为 peaks_ee.xpk 的文件中读取的字典。

来自 peaks_ee.xpk 的样本:

label dataset sw sf
1H 1H_2
NOESY_F1eF2e.nv
4807.69238281 4803.07373047
600.402832031 600.402832031
1H.L 1H.P 1H.W 1H.B 1H.E 1H.J 1H.U 1H_2.L 1H_2.P 1H_2.W 1H_2.B 1H_2.E 1H_2.J 1H_2.U vol int stat comment flag0 flag8 flag9
0 {1.H1'} 5.82020 0.05000 0.10000 ++ {0.0} {} {2.H8} 7.61004 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
1 {2.H8} 7.61004 0.05000 0.10000 ++ {0.0} {} {1.H1'} 5.82020 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
2 {1.H8} 8.13712 0.05000 0.10000 ++ {0.0} {} {1.H1'} 5.82020 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
3 {1.H1'} 5.82020 0.05000 0.10000 ++ {0.0} {} {1.H8} 8.13712 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
4 {2.H8} 7.61004 0.05000 0.10000 ++ {0.0} {} {2.H1'} 5.90291 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
5 {2.H1'} 5.90291 0.05000 0.10000 ++ {0.0} {} {2.H8} 7.61004 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
6 {2.H8} 7.61004 0.05000 0.10000 ++ {0.0} {} {1.H1'} 5.82020 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
7 {2.H8} 7.61004 0.05000 0.10000 ++ {0.0} {} {1.H8} 8.13712 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
8 {1.H1'} 5.82020 0.05000 0.10000 ++ {0.0} {} {2.H8} 7.61004 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
9 {1.H8} 8.13712 0.05000 0.10000 ++ {0.0} {} {2.H8} 7.61004 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
10 {3.H6} 7.53261 0.05000 0.10000 ++ {0.0} {} {4.H1'} 5.74125 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
11 {4.H1'} 5.74125 0.05000 0.10000 ++ {0.0} {} {3.H6} 7.53261 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
12 {3.H1'} 5.54935 0.05000 0.10000 ++ {0.0} {} {4.H8} 7.49932 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
13 {4.H8} 7.49932 0.05000 0.10000 ++ {0.0} {} {3.H1'} 5.54935 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
14 {3.H6} 7.53261 0.05000 0.10000 ++ {0.0} {} {3.H1'} 5.54935 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
15 {3.H1'} 5.54935 0.05000 0.10000 ++ {0.0} {} {3.H6} 7.53261 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
16 {3.H6} 7.53261 0.05000 0.10000 ++ {0.0} {} {2.H1'} 5.90291 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
17 {3.H6} 7.53261 0.05000 0.10000 ++ {0.0} {} {2.H8} 7.61004 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
18 {2.H1'} 5.90291 0.05000 0.10000 ++ {0.0} {} {3.H6} 7.53261 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
19 {2.H8} 7.61004 0.05000 0.10000 ++ {0.0} {} {3.H6} 7.53261 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
20 {4.H8} 7.49932 0.05000 0.10000 ++ {0.0} {} {4.H1'} 5.74125 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
21 {4.H1'} 5.74125 0.05000 0.10000 ++ {0.0} {} {4.H8} 7.49932 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
22 {4.H8} 7.49932 0.05000 0.10000 ++ {0.0} {} {3.H1'} 5.54935 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
23 {4.H8} 7.49932 0.05000 0.10000 ++ {0.0} {} {3.H6} 7.53261 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0
24 {3.H1'} 5.54935 0.05000 0.10000 ++ {0.0} {} {4.H8} 7.49932 0.05000 0.10000 ++ {0.0} {} 0.0 100.0000 0 {} 0 0 0`

以 peaks_ee.xpk 的第 0 行为例,原子名称为 1.H1',其化学位移为 5.82020。在同一行的第 8 列中,还有另一个原子名称 2.H8,其化学位移为 7.61004。基本上我想检查行中的第一个化学位移(5.82020)是否在某个范围内,以及第二个化学位移(7.49932)是否在另一个范围内。如果是,则将原子名称(1.H1' 和 2.H8)写到名为 tclust.txt 的文件中

这是到目前为止的代码,我之前发布了另一个问题,@wwii 帮助我处理了这段代码。

pattern = '''{(\d\.H\d'?)}\s(\d\.\d+)\s'''
rex = re.compile(pattern)

j = 0;
contents_atom = []
atom_lines=[]

result = {}
with open("peaks_ee.xpk","r") as atom_name:
    for line in atom_name:
        for match in rex.finditer(line):
            name, shift = match.groups()
            if name not in result:
                result[name] = float(shift)
                print (name,shift)
                    if filename == 'ee_pinkH1.xpk':
                        if result[name]<=8.5
                            float_str = re.findall("\d\.\H\d'?",name)
                            if (len(float_str))>1:
                                j=j+1
                                value1 = ('Atom ' + str(j) + ' ' + str(float_str[0])+ ' ' + str(float_str[1])+ '\n')
                                atom_lines.insert(-1,value1)

tclust_atom = open("tclust.txt","a")
for value1 in atom_lines:
    tclust_atom.write(value1)
tclust_atom.close()

这是从print (names,shift) 行打印出来的原子名称及其化学位移列表的图片

atom names and chemical shifts

从那张图中,前两行是:

"1.H1'","5.82020" "2.H8","7.61004" 但前两行实际上只是来自 peaks_ee.xpk 的第一行,我想看看“5.82020”是否介于 5.1 和 6 之间,以及 7.61004 是否介于 7 和 8.25 之间。有没有办法通过使用字典的值来做到这一点?我注意到每隔一行将是我想要查看它们是否在 5.1 和 6 之间的值,而交替值是我想要查看它们是否在 7 和 8.25 之间的值。

编辑:这是我的完整代码:

import pandas as pd
import os
import sys
import re

i=0;
contents_peak=[]
peak_lines=[]
with open ("ee_pinkH1.xpk","r") as peakPPM:
    for PPM in peakPPM.readlines():
        float_num = re.findall("[\s][1-9]{1}\.[0-9]+",PPM)
        if (len(float_num)>1):
            i=i+1
            value = ('Peak '+ str(i) + ' ' + str(float_num[0]) + ' 0.05 ' + str(float_num[1]) + ' 0.05 ' + '\n')
            peak_lines.insert(-1,value)
tclust_peak = open("tclust.txt","w+")
tclust_peak.write("rbclust \n")
for value in peak_lines:
    tclust_peak.write(value)
tclust_peak.close()

pattern = '''{\d\.H\d'?)}\s(\d\.\d+)\s'''
rex = re.compile(pattern)

j=0;
contents_atom=[]
atom_lines=[]
result = {}
with open("peaks_ee.xpk","r") as atomName:
    for name in atomName:
        for match in rex.finditer(line):
            name,shift = match.groups()
            print (name,shift)
            if name not in result:
                result[name]=float(shift)
                float_str = re.findall("\d\.H\d'?",name)
                if (len(float_str)>1):
                    j=j+1
                    value1 = ('Atom ' +str(j)+ ' ' + str(float_str[0])+ ' ' + str(float_str[1]) + '\n')
                    atom_lines.insert(-1,value)

df = pd.read_csv("D:/tmp/peaks_ee.xpk", sep= " ", skiprows=5)

shift1= df["1H.P"]
shift2= df["1H_2.P"]

mask = ((shift1>5.1) & (shift1<6)) & ((shift2>7) & (shift2<8.25))

result = df[mask]
result = result[["1H.L","1H.P","1H_2.L","1H_2.P"]]
print result

tclust_atom = open("tclust.txt","a")
for value1 in atom_lines:
    tclust_atom.write(value1)
tclust_atom.close()

这是我得到的错误:

Traceback (most recent call last):
  File "pandas.py", line 1, in <module>
    import pandas as pd 
  File "/Users/malaikaiyer/Downloads/nmrfxstructure/nmrfxstructure/target/structure-10.1.1-bin/structure-10.1.1/pandas.py", line 23, in <module>
rex = re.compile(pattern)
  File "/Users/malaikaiyer/Downloads/nmrfxstructure/nmrfxstructure/target/structure-10.1.1-bin/structure-10.1.1/lib/jython-standalone-2.7.0.jar/Lib/re.py", line 190, in compile
  File "/Users/malaikaiyer/Downloads/nmrfxstructure/nmrfxstructure/target/structure-10.1.1-bin/structure-10.1.1/lib/jython-standalone-2.7.0.jar/Lib/re.py", line 242, in _compile
sre_constants.error: unbalanced parenthesis

编辑:最新代码 7/26:

import pandas as pd
import os
import sys
import re
import csv 

i=0;
contents_peak=[]
peak_lines=[]
with open ("ee_pinkH1.xpk","r") as peakPPM:
    for PPM in peakPPM.readlines():
        float_num = re.findall("[\s][1-9]{1}\.[0-9]+",PPM)
        if (len(float_num)>1):
            i=i+1
            value = ('Peak '+ str(i) + ' ' + str(float_num[0]) + ' 0.05 ' + str(float_num[1]) + ' 0.05 ' + '\n')
            peak_lines.insert(-1,value)
tclust_peak = open("tclust.txt","w+")
tclust_peak.write("rbclust \n")
for value in peak_lines:
    tclust_peak.write(value)
tclust_peak.close()

pattern = ‘’’{(\d\.H\d’?)}\s(\d\.\d+)\s'''
rex = re.compile(pattern)

j=0;
contents_atom=[]
atom_lines=[]
result = {}
text = ‘ee’

if text == ‘ee’:
    df = pd.read_csv('peaks_ee.xpk', sep=" ",skiprows=5)

    shift1= df["1H.P"]
    shift= df["1H_2.P"]
    if filename == 'ee_pinkH1.xpk'
        mask = ((shift1>5.1) & (shift1<6)) & ((shift2>7) & (shift2<8.25))
    elif filename == 'ee_pinkH2.xpk'
        mask = ((shift1>3.25)&(shift1<5))&((shift2>7)&(shift2<8.5))
    result = df[mask]
    result = result[["1H.L","1H.P","1H_2.L","1H_2.P"]]
    result.to_csv("result.csv")

if text == ‘ef’:
    df = pd.read_csv('peaks_ef.xpk', sep=" ",skiprows=5)

    shift1= df["1H.P"]
    shift2= df["1H_2.P"]
    if filename == ‘ef_blue.xpk’:
        mask = ((shift1>5) & (shift1<6)) & ((shift2>7.25) & (shift2<8.25))
    elif filename == ‘ef_green.xpk’:
        mask = ((shift1>7) & (shift1<9)) & ((shift2>5.25) & (shift2<6.2))
    elif filename == ‘ef_orange:
        mask = ((shift1>3) & (shift1<5)) & ((shift2>5.2) & (shift2<6.25))
    result = df[mask]
    result = result[["1H.L","1H.P","1H_2.L","1H_2.P"]]
    result.to_csv("result.csv")

if text == ‘fe’:
    df = pd.read_csv('peaks_fe.xpk', sep=" ",skiprows=5)

    shift1= df[“Atom1”]
    shift2= df[“Atom2”]
    if filename == ‘fe_yellow’:
        mask = ((shift1>3) & (shift1<5)) & ((shift2>5) & (shift2<6))
    elif filename == ‘fe_green’:
        mask = ((shift1>5.1) & (shift1<6)) & ((shift2>7) & (shift2<8.25))
        result = df[mask]
        result = result[["1H.L","1H.P","1H_2.L","1H_2.P"]]
        result.to_csv("result.csv")

tclust_peak = open("tclust.txt”,”a")
tclust_peak.write((str(result))
tclust_atom.close()

【问题讨论】:

  • 你的文本文件吓到我了。
  • 老实说,Python 也让我害怕。这么多的嵌套。我觉得必须有更好的方法来做到这一点。
  • 您最好使用pandas.DataFrame。在那里,您可以轻松访问单个列,并可以轻松地对其应用条件。
  • 您的缩进无效。
  • 是的,我很确定嵌套不好,但我不知道该怎么做@CoryMadden

标签: python python-2.7 pandas dictionary


【解决方案1】:

您可以尝试使用pandas 包。

以下代码将加载您的文件并跳过前五行以加载您想要的数据。然后它会在列之间逐位检查以创建掩码,最后选择您想要的列。

import pandas as pd
df = pd.read_csv("peaks_ee.xpk", sep=" ", skiprows=5)

shift1 = df["1H.P"]
shift2 = df["1H_2.P"]

mask = ((shift1>5.1) & (shift1<6)) & ((shift2>7) & (shift2<8.25))

result = df[mask]
result = result[["1H.L","1H.P","1H_2.L","1H_2.P"]]

结果如下:

>>> result
       1H.L     1H.P  1H_2.L   1H_2.P
0   {1.H1'}  5.82020  {2.H8}  7.61004
3   {1.H1'}  5.82020  {1.H8}  8.13712
5   {2.H1'}  5.90291  {2.H8}  7.61004
8   {1.H1'}  5.82020  {2.H8}  7.61004
11  {4.H1'}  5.74125  {3.H6}  7.53261
12  {3.H1'}  5.54935  {4.H8}  7.49932
15  {3.H1'}  5.54935  {3.H6}  7.53261
18  {2.H1'}  5.90291  {3.H6}  7.53261
21  {4.H1'}  5.74125  {4.H8}  7.49932
24  {3.H1'}  5.54935  {4.H8}  7.49932

然后,如果您愿意,可以将result 导出为 csv 文件,如下所示:

result.to_csv("result.csv")

我不确定这段代码是否正是您所需要的,但它可能是您了解如何使用pandas 的良好开端。

【讨论】:

  • 嘿,谢谢你帮助我!我无法运行代码,我将编辑我的问题,以便您查看我遇到的错误以及我的代码图片。
  • 您是否仅尝试了我提供的代码?结果的输出是否符合您的预期?
  • 嗨,我试过你提供的代码。我在我的问题中将其编写为一个编辑,并显示了我得到的错误是什么
  • 我意识到我的代码存在某些问题,但现在代码中的所有内容似乎在语法上都是正确的。但现在我唯一的错误是:AttributeError: 'module' object has no attribute 'read_csv'
  • 你能更新你运行的代码吗?我仍然想知道我在回答中所说的输出是否符合您的期望。
猜你喜欢
  • 2021-11-05
  • 1970-01-01
  • 1970-01-01
  • 2021-04-01
  • 1970-01-01
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多