解析平面文件(位置文本文件)以读取波长
Parse flat-file (positional text-file) to read the wavelength
我有下一个包含数据的 txt:
FI R 83.0000m 34.960 1.1262 Fe 2 1.32055m 33.626 0.0522 N
2 5754.61A 33.290 0.0241
TI R 1800.00m 33.092 0.0153 Fe 2 1.24854m 32.645 0.0054 N
2 915.612A 31.997 0.0012
NI Ra 2.85000m 36.291 24.1132 Fe 2 7637.54A 33.077 0.0147
我想要的是获取第三列,是出射线的波长,但是我的问题是把条件放在if里面。
Name1,ion1,wavelength1,da1,de1,name2,ion2,
wavelength2,da2,de2,name3,ion3,wavelength3,da3,de3=np.genfromtxt('Emergent_line.txt',
skip_header=3, delimiter="", unpack=True)
if(Name1=="Fe" and ion1==2):
print(wavelength1)
elif(name2=="Fe" and ion2==2):
print(wavelength2)
elif(name3=="Fe" and ion3==2):
print(wavelength3)
在文本中我想找到 Fe 2 的波长,但我认为问题在于波长末尾有一个字母,我不想删除,因为我有一个很大的列表.我又试了一个from,还是没解决
我认为你最好使用正则表达式
示例:
import re
text = '''FI R 83.0000m 34.960 1.1262 Fe 2 1.32055m 33.626 0.0522 N
2 5754.61A 33.290 0.0241
TI R 1800.00m 33.092 0.0153 Fe 2 1.24854m 32.645 0.0054 N
2 915.612A 31.997 0.0012
NI Ra 2.85000m 36.291 24.1132 Fe 2 7637.54A 33.077 0.0147'''
find_this = re.findall('(Fe 2.*?[0-9].*?)\s', text)
print(find_this)
输出:
['Fe 2 1.32055m', 'Fe 2 1.24854m', 'Fe 2 7637.54A']
[Program finished]
或者如果您只想要值。
find_this = re.findall('Fe 2.*?([0-9].*?)\s', text)
输出:
['1.32055m', '1.24854m', '7637.54A']
[Program finished]
回答新问题
下面是一个示例,说明如何使用 for 循环并将 var 转换为 float 来实现挑选 1.35 - 1.40 之间的值。现在我们可以在这一行中使用条件:
if (float_value >= 1.35) and (float_value <= 1.40):
print(value)
如果匹配,它会打印未触及的字符串,保留结尾字母。
完整代码如下:
(我缩短了文字以便于阅读)
import re
text = '''Fe 2 1.405A 33.077 0.0147
Fe 2 1.305A 33.077 0.0147
Fe 2 1.345A 33.077 0.0147
Fe 2 1.35A 33.077 0.0147
Fe 2 1.35623A 33.077 0.0147
Fe 2 1.40A 33.077 0.0147
Fe 2 1.37A 33.077 0.0147
Fe 2 1.41A 33.077 0.0147'''
find_this = re.findall('Fe 2.*?([0-9].*?)\s', text)
for value in find_this:
del_letters = re.sub('[A-Za-z]', '', value)
float_value = float(del_letters)
if (float_value >= 1.35) and (float_value <= 1.40):
print(value)
输出:
1.35A
1.35623A
1.40A
1.37A
这是另一个想法,没有使用 re
模块:
someText ='FI R 83.0000m 34.960 1.1262'
someText.split()
#>> ['FI', 'R', '83.0000m', '34.960', '1.1262']
name1,ion1, lambda1, *other = someText.split()
lambda1 = float(lambda1[0:-1])
print(lambda1, other)
#>> 83.0 ['34.960', '1.1262']
您可以使用 .split()
str 方法,该方法在分隔数据的空白处进行拆分,而无需使用正则表达式。
Regex 非常适合提取更复杂的文本格式,通常是在输入变化时。由于在这种情况下输入并没有真正变化,您也可以改用更简单的 str
方法。
您提供的 text-file 似乎是 flat-file 或 fixed-with 数据(列)布局的文件
- 作为位置文本(每列从预定义位置开始)
- 采用 fixed-width 格式(每列有一个 fixed-width)
Pandas 有一个读取 fixed-width 文件的方法
你可以使用 pandas
and their IO tools method read_fwf
.
import io # just for demonstration without needing a file
import pandas
text = '''FI R 83.0000m 34.960 1.1262 Fe 2 1.32055m 33.626 0.0522 N
2 5754.61A 33.290 0.0241
TI R 1800.00m 33.092 0.0153 Fe 2 1.24854m 32.645 0.0054 N
2 915.612A 31.997 0.0012
NI Ra 2.85000m 36.291 24.1132 Fe 2 7637.54A 33.077 0.0147'''
buffer = io.StringIO(text) # just a helper to read from text as from file
filepath_or_buffer = buffer # can also be the file-path directly
df = pandas.read_fwf(filepath_or_buffer, colspecs='infer', widths=None, infer_nrows=100, header=None)
print(df) # df represented as complete table read
wave_lengths = df.loc[(df[3] == 'Fe') & (df[4] == 2)][5]
print("== Wavelengths:")
print(wave_lengths)
buffer.close()
打印:
0 1 2 3 4 5 6 7 8
0 FI R 83.0000m 34.960 1.1262 Fe 2.0 1.32055m 33.626 0.0522 N
1 2 NaN 5754.61A 33.290 0.0241 NaN NaN NaN NaN NaN NaN
2 TI R 1800.00m 33.092 0.0153 Fe 2.0 1.24854m 32.645 0.0054 N
3 2 NaN 915.612A 31.997 0.0012 NaN NaN NaN NaN NaN NaN
4 NI Ra 2.85000m 36.291 24.1132 Fe 2.0 7637.54A 33.077 0.0147 NaN
== Wavelengths:
0 1.32055m
2 1.24854m
4 7637.54A
注:
- Python 的
io.StringIO
被用作模拟缓冲区而不是文件的助手。
- Panda 的
loc
方法定位或过滤 Fe 2
行,其中我们用波长 打印第 5 列
另见
- 迈向数据科学:Parsing Fixed Width Text Files with Pandas | by Amy Rask
- Pandas' IO tools (text, CSV, HDF5, …)
- Parsing out data from a flat file
- python - Parsing a text file into a pandas DataFrame - Code Review Stack Exchange
- How to efficiently parse fixed width files?
我有下一个包含数据的 txt:
FI R 83.0000m 34.960 1.1262 Fe 2 1.32055m 33.626 0.0522 N
2 5754.61A 33.290 0.0241
TI R 1800.00m 33.092 0.0153 Fe 2 1.24854m 32.645 0.0054 N
2 915.612A 31.997 0.0012
NI Ra 2.85000m 36.291 24.1132 Fe 2 7637.54A 33.077 0.0147
我想要的是获取第三列,是出射线的波长,但是我的问题是把条件放在if里面。
Name1,ion1,wavelength1,da1,de1,name2,ion2,
wavelength2,da2,de2,name3,ion3,wavelength3,da3,de3=np.genfromtxt('Emergent_line.txt',
skip_header=3, delimiter="", unpack=True)
if(Name1=="Fe" and ion1==2):
print(wavelength1)
elif(name2=="Fe" and ion2==2):
print(wavelength2)
elif(name3=="Fe" and ion3==2):
print(wavelength3)
在文本中我想找到 Fe 2 的波长,但我认为问题在于波长末尾有一个字母,我不想删除,因为我有一个很大的列表.我又试了一个from,还是没解决
我认为你最好使用正则表达式
示例:
import re
text = '''FI R 83.0000m 34.960 1.1262 Fe 2 1.32055m 33.626 0.0522 N
2 5754.61A 33.290 0.0241
TI R 1800.00m 33.092 0.0153 Fe 2 1.24854m 32.645 0.0054 N
2 915.612A 31.997 0.0012
NI Ra 2.85000m 36.291 24.1132 Fe 2 7637.54A 33.077 0.0147'''
find_this = re.findall('(Fe 2.*?[0-9].*?)\s', text)
print(find_this)
输出:
['Fe 2 1.32055m', 'Fe 2 1.24854m', 'Fe 2 7637.54A']
[Program finished]
或者如果您只想要值。
find_this = re.findall('Fe 2.*?([0-9].*?)\s', text)
输出:
['1.32055m', '1.24854m', '7637.54A']
[Program finished]
回答新问题
下面是一个示例,说明如何使用 for 循环并将 var 转换为 float 来实现挑选 1.35 - 1.40 之间的值。现在我们可以在这一行中使用条件:
if (float_value >= 1.35) and (float_value <= 1.40):
print(value)
如果匹配,它会打印未触及的字符串,保留结尾字母。
完整代码如下: (我缩短了文字以便于阅读)
import re
text = '''Fe 2 1.405A 33.077 0.0147
Fe 2 1.305A 33.077 0.0147
Fe 2 1.345A 33.077 0.0147
Fe 2 1.35A 33.077 0.0147
Fe 2 1.35623A 33.077 0.0147
Fe 2 1.40A 33.077 0.0147
Fe 2 1.37A 33.077 0.0147
Fe 2 1.41A 33.077 0.0147'''
find_this = re.findall('Fe 2.*?([0-9].*?)\s', text)
for value in find_this:
del_letters = re.sub('[A-Za-z]', '', value)
float_value = float(del_letters)
if (float_value >= 1.35) and (float_value <= 1.40):
print(value)
输出:
1.35A
1.35623A
1.40A
1.37A
这是另一个想法,没有使用 re
模块:
someText ='FI R 83.0000m 34.960 1.1262'
someText.split()
#>> ['FI', 'R', '83.0000m', '34.960', '1.1262']
name1,ion1, lambda1, *other = someText.split()
lambda1 = float(lambda1[0:-1])
print(lambda1, other)
#>> 83.0 ['34.960', '1.1262']
您可以使用 .split()
str 方法,该方法在分隔数据的空白处进行拆分,而无需使用正则表达式。
Regex 非常适合提取更复杂的文本格式,通常是在输入变化时。由于在这种情况下输入并没有真正变化,您也可以改用更简单的 str
方法。
您提供的 text-file 似乎是 flat-file 或 fixed-with 数据(列)布局的文件
- 作为位置文本(每列从预定义位置开始)
- 采用 fixed-width 格式(每列有一个 fixed-width)
Pandas 有一个读取 fixed-width 文件的方法
你可以使用 pandas
and their IO tools method read_fwf
.
import io # just for demonstration without needing a file
import pandas
text = '''FI R 83.0000m 34.960 1.1262 Fe 2 1.32055m 33.626 0.0522 N
2 5754.61A 33.290 0.0241
TI R 1800.00m 33.092 0.0153 Fe 2 1.24854m 32.645 0.0054 N
2 915.612A 31.997 0.0012
NI Ra 2.85000m 36.291 24.1132 Fe 2 7637.54A 33.077 0.0147'''
buffer = io.StringIO(text) # just a helper to read from text as from file
filepath_or_buffer = buffer # can also be the file-path directly
df = pandas.read_fwf(filepath_or_buffer, colspecs='infer', widths=None, infer_nrows=100, header=None)
print(df) # df represented as complete table read
wave_lengths = df.loc[(df[3] == 'Fe') & (df[4] == 2)][5]
print("== Wavelengths:")
print(wave_lengths)
buffer.close()
打印:
0 1 2 3 4 5 6 7 8
0 FI R 83.0000m 34.960 1.1262 Fe 2.0 1.32055m 33.626 0.0522 N
1 2 NaN 5754.61A 33.290 0.0241 NaN NaN NaN NaN NaN NaN
2 TI R 1800.00m 33.092 0.0153 Fe 2.0 1.24854m 32.645 0.0054 N
3 2 NaN 915.612A 31.997 0.0012 NaN NaN NaN NaN NaN NaN
4 NI Ra 2.85000m 36.291 24.1132 Fe 2.0 7637.54A 33.077 0.0147 NaN
== Wavelengths:
0 1.32055m
2 1.24854m
4 7637.54A
注:
- Python 的
io.StringIO
被用作模拟缓冲区而不是文件的助手。 - Panda 的
loc
方法定位或过滤Fe 2
行,其中我们用波长 打印第 5 列
另见
- 迈向数据科学:Parsing Fixed Width Text Files with Pandas | by Amy Rask
- Pandas' IO tools (text, CSV, HDF5, …)
- Parsing out data from a flat file
- python - Parsing a text file into a pandas DataFrame - Code Review Stack Exchange
- How to efficiently parse fixed width files?