Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用ython读取文本文件中不带空格的数字_Python - Fatal编程技术网

Python 使用ython读取文本文件中不带空格的数字

Python 使用ython读取文本文件中不带空格的数字,python,Python,我是Python的新手,很难阅读这样的文本文件: 0.42617E-03-0.19725E+09-0.21139E+09 0.37077E+08 0.85234E-03-0.18031E+09-0.18340E+09 0.28237E+08 0.12785E-02-0.16583E+09-0.15887E+09 0.20637E+08 因此,文件中的数字之间没有逗号或空格分隔符。 使用Matlab我知道如何指定格式,但如何在Python中实现 我一直在尝试np.loadtxt,但不

我是Python的新手,很难阅读这样的文本文件:

  0.42617E-03-0.19725E+09-0.21139E+09 0.37077E+08
  0.85234E-03-0.18031E+09-0.18340E+09 0.28237E+08
  0.12785E-02-0.16583E+09-0.15887E+09 0.20637E+08
因此,文件中的数字之间没有逗号或空格分隔符。 使用Matlab我知道如何指定格式,但如何在Python中实现

我一直在尝试np.loadtxt,但不知道如何设置要读取的位数,所以如果有人能给我一个提示,我将不胜感激

提前感谢,,
Erik

为了扩展我的评论,基于您可以用MATLAB成功解析这个事实,我假设这些字段是固定宽度的。在这种情况下,您可以根据字段宽度对每一行进行切片,然后根据需要将其转换为numpy数组。例如:

import numpy

input_data = """ 0.42617E-03-0.19725E+09-0.21139E+09 0.37077E+08
 0.85234E-03-0.18031E+09-0.18340E+09 0.28237E+08
 0.12785E-02-0.16583E+09-0.15887E+09 0.20637E+08
"""
input_rows = input_data.split('\n')

width = 12
num_fields = 4

data = []
for input_row in input_rows:
    if not input_row:
        continue
    data.append([float(input_row[width * i:width * (i + 1)].strip()) for i in range(num_fields)])

data = numpy.array(data)
print(data)
这将产生:

[[  4.26170000e-04  -1.97250000e+08  -2.11390000e+08   3.70770000e+07]
 [  8.52340000e-04  -1.80310000e+08  -1.83400000e+08   2.82370000e+07]
 [  1.27850000e-03  -1.65830000e+08  -1.58870000e+08   2.06370000e+07]]

当然,本例使用固定字符串表示输入数据,但您可以想象对输入流执行类似的操作。

您可能会滥用这样一个事实,即您的数字似乎都是用科学记数法表示的,并使用正则表达式来提取每个数字

import re

e_numbers = re.compile(r"[\d.]*?E[+-]\d{2}")

with open('yourfile.txt') as f:
    numbers = [float(num) for lst in [e_numbers.findall(line) for line in f] for num in lst]
要拉出该正则表达式,请执行以下操作:

e_numbers = re.compile(r'''
    [\d.]*?             # zero or more of the following:
                        #   0123456789.
                        # matching the fewest possible
    E                   # the literal letter 'E'
    [+-]                # either a literal '+' or a literal '-'
    \d{2}               # followed by two digits 0-9''', re.X)

其他答案使用的方法依赖于数字宽度相同的事实,或者使用科学方法。在这里,我提出了一个方法,它接受浮点数的任何表示,无论是否为固定宽度

如果用C语言处理给定的输入,可能会使用
scanf
sscanf
。Python具有与
printf
类似的功能(例如字符串的
格式
方法),但它没有类似于
scanf
sscanf
的功能

幸运的是,您可以在Python标准库中直接使用
sscanf
函数。以下示例适用于Linux系统上的Python:

导入ctypes
libc=ctypes.CDLL(“libc.so.6”)
sscanf=libc.sscanf
以开放(“测试”)作为fp:
对于fp中的l:
float_1=ctypes.c_float()
float_2=ctypes.c_float()
float_3=ctypes.c_float()
float_4=ctypes.c_float()
sscanf(ctypes.create_string_buffer(字节(l,“utf8”))、b“%f%f%f”、ctypes.byref(float_1)、ctypes.byref(float_2)、ctypes.byref(float_3)、ctypes.byref(float_4))
#您可以检查sscanf的返回值是否存在错误。当每个
打印(浮点值1.value、浮点值2.value、浮点值3.value、浮点值4.value)
输出是

0.00042617000872269273 -197250000.0 -211390000.0 37077000.0
0.0008523400174453855 -180310000.0 -183400000.0 28237000.0
0.0012784999562427402 -165830000.0 -158870000.0 20637000.0
如果您的系统不使用glibc或使用旧版本(不太可能),请相应地更改库的路径。(您的系统不太可能没有C库或该库不实现scanf)如果您使用的是Windows,请将
libc=ctypes.CDLL(“libc.so.6”)
更改为

libc = ctypes.cdll.msvcrt # Loads MS standard C Library
ctypes
仅使用标准调用约定调用动态库中的函数。您可以使用它将Python代码与几乎任何C库进行接口


如果您不想使用
ctypes
,那么您可以使用一些社区库,例如或,它们都实现了
scanf

的功能。我想您正在寻找
split()
regex
,如果需要的话?请说明您希望如何解析此内容。如果字段宽度是固定的,您可以使用切片。@JCVanHamme:它们看起来确实是固定宽度的---示例中的最后一列前面有一个空格,其中
+
-
与第一列一样(给定或获取标记格式错误)。这不是保证,但可能已经足够好了。我建议你查阅这些数据的来源,无论是个人还是程序。寻找某种标准,然后是产生它的代码,然后是任何“负责人”,他们可以告诉你输出应该遵守什么规则。如果你找不到这些数据的任何规则,你就会陷入猜测,不得不接受一个脆弱的“尚未打破”的解决方案。一行:
np.array([[float(ln[(12*i:(12*(i+1))])for i in range(len(ln)/12)]for ln in open(“data.txt”))
这是一种有趣的切片方法。我更喜欢使用range的
步骤
,因为它可以让您不必知道有多少个字段(或者确实需要做很多数学运算)<代码>[行[i:i+宽度]表示i在范围内(0,长度(行),宽度)]感谢您的所有回答。我没有让它工作,而是手动编辑文本文件以与“loadtxt”兼容。我真的是Python的新手(感觉阅读一个文件需要很多代码),在理解你的答案之前,我需要学习更多。