У меня есть текстовый файл с данными, которые я пытаюсь прочитать на Python:

OMEGA2    1.450E+00 1.500E+00 1.550E+00 1.600E+00 1.650E+00 1.700E+00
OMEGA2    1.800E+00 1.850E+00 1.900E+00 1.950E+00 2.000E+00 2.050E+00
F2REAL    1.146E+00 -1.015E+03-2.206E+03-2.618E+03-2.288E+03-1.400E+03
F2REAL    6.255E+00 -3.254E+02-8.150E+02-1.060E+03-9.749E+02-5.995E+02
F2REAL    1.754E+01 -1.530E+02-4.375E+02-5.932E+02-5.618E+02-3.536E+02
F2REAL    1.740E+01 -7.981E+01-2.525E+02-3.748E+02-3.891E+02-2.739E+02
OMEGA2    1.800E+00 1.850E+00 1.900E+00 1.950E+00 2.000E+00 2.050E+00

Теперь мне нужны только значения, в которых строка начинается с F2REAL; В каждой строке я хочу извлечь 6 значений. Значение1 от индекса 11 до индекса 20, значение от индекса 21 до 30, ..., значение 6 от индекса 61:70

Я пробовал следующее:

file = 'file.txt'
STR1 = 'F2REAL'

def get_data():
    with open(file) as f:
        hyd_all = f.readlines()
        for line in hyd_all:
            if STR1 in line:
                print([float(line[10:19]),float(line[20:29])])

get_data()
  1. Это не читает E-power, так как я получаю [1.146, -1.015, ..]. Как мне это правильно получить?
  2. Есть ли способ лучше вместо того, чтобы писать 10: 19,20: 29, .. 60:69? Все интересующие строки состоят из 6 столбцов и всегда начинаются с 10 * i.
  3. Я хочу добавить каждый результат в матрицу. В этом примере 4 строки и 6 столбцов
2
Jeroen 13 Фев 2021 в 11:42

4 ответа

Лучший ответ
  1. Электронная нотация - это просто нотация. Значения анализируются правильно, просто представлены по-разному

  2. вы можете использовать понимание списка

  3. Предполагая, что вы говорите о numpy - матрице (в противном случае просто переключитесь на pandas DataFrame):

import numpy as np


def get_data(path: str, target: str, width: int = 10):
    values = []
    with open(path, 'r') as f:
        for line in f.readlines():
            # 'F2REAL' should be at the beginning of the line not just anywhere
            if line.startswith(target):
                # map sequential fixed widths to float
                values.append([float(line[width*i:width*(i+1)]) for i in range(1, 7)])

    return np.asarray(values)
    

print(get_data('file.txt', 'F2REAL'))

Выход:

[[ 1.146e+00 -1.015e+03 -2.206e+03 -2.618e+03 -2.288e+03 -1.400e+03]
 [ 6.255e+00 -3.254e+02 -8.150e+02 -1.060e+03 -9.749e+02 -5.995e+02]
 [ 1.754e+01 -1.530e+02 -4.375e+02 -5.932e+02 -5.618e+02 -3.536e+02]
 [ 1.740e+01 -7.981e+01 -2.525e+02 -3.748e+02 -3.891e+02 -2.739e+02]]
2
Stefan B 13 Фев 2021 в 09:22
file = 'file.txt'
STR1 = 'F2REAL'

def get_data():
    with open(file) as f:
        hyd_all = f.readlines()
        for line in hyd_all:
            if STR1 in line:
                print(line[10:20],line[20:30],line[30:40],line[40:50],line[50:60],line[60:70])

get_data()

Результаты будут примерно такими:

enter image description here

0
Ajay Singh 13 Фев 2021 в 08:55
def parse_scientific(s):
    root = float(s.split('E')[0])
    exp  = int(s.split('E')[1])
    return root*(10**exp)

def get_data():
    with open(file) as f:
        hyd_all = f.readlines()
        for line in hyd_all:
            if line.startswith(STR1):
                item_values = [parse_scientific(line[offset*10:offset*10+10]) for offset in range(1,7)]

Используйте item_values для вставки в матрицу

0
Chance 13 Фев 2021 в 09:08

Ваш файл относится к категории файлов с фиксированной шириной. Я предлагаю вам использовать библиотеку Pandas, в которой есть специальная функция для чтения таких файлов, read_fwf. Функция read_fwf принимает аргумент colspecs, который представляет собой список кортежей, каждый кортеж содержит начало и конец определенного столбца. Поскольку в вашем файле нет столбца заголовка, вы должны использовать header=None, и вашим столбцам будут автоматически присвоены номера (которые вы затем можете изменить на собственные имена или добавить столбец заголовка в свой файл).

Эта функция распознает научную нотацию (E + 0 ...) и анализирует ваши числа как действительные числа, а не строки. Затем вы можете изменить формат отображения чисел на как вам нравится.

import pandas as pd


colspecs = [(0, 6), (10, 19), (20, 30), (30, 40), (40, 50), (50, 60), (60, 70)]
df = pd.read_fwf("file.txt", header=None, colspecs=colspecs)

Если возможно, я предлагаю вам использовать Pandas: это очень мощная библиотека, и вы можете выполнять множество операций с вашими данными, таких как построение графиков, запросы или расчет статистики. Код также очень лаконичный.

0
Enrico Gandini 13 Фев 2021 в 09:13
66183285