извлечение значений параметров из одной большой строки - PullRequest
1 голос
/ 10 июля 2019

У меня есть следующая строка (загруженная из файла .txt в ячейку Matlab):

text = 'u1 @ t=0, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.01, K=3.1416, 
gamma=0.1, A=-0.1 u1 @ t=0.02, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.03, 
K=3.1416, gamma=0.1, A=-0.1'

Вся строковая переменная очень длинная (от t = 0 до t = 1 и для разных значений параметров). Я хочу разделить их на несколько ячеек, чтобы

  • A(1)='u1 @ t=0, K=3.1416, gamma=0.1, A=-0.1',
  • A(2)='u1 @ t=0.01, K=3.1416, gamma=0.1, A=-0.1'

  • и т.д.

    Или еще лучше - извлечь переменные параметров t, K, gamma, A и сохранить их в массиве.

Как это сделать в Matlab? (или в Python)

Edit:

Оказывается, первые несколько записей в моих данных имеют вид ... t=1E-4, ... t=2E-4, ...... t=9E-4, ... t=0.001, и некоторые ответы пропустят первые несколько временных шагов, которые содержатся в научных записях. Как справиться с этими цифрами?

Ответы [ 8 ]

1 голос
/ 11 июля 2019

Вы получили много ответов на Python, так что вот ответ MATLAB.Вы можете использовать функцию regexp для анализа строки, затем vertcat, cellfun и str2doubleизменить форму и преобразовать полученный массив ячеек строк в матрицу значений N на 4.Начиная с этого примера данных (4 набора записей в одной строке):

str = 'u1 @ t=0, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.01, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.02, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.03, K=3.1416, gamma=0.1, A=-0.1';

Код состоит всего из 2 строк:

vals = regexp(str, 'u1 @ t=([-\.\dE]+), K=([-\.\dE]+), gamma=([-\.\dE]+), A=([-\.\dE]+)', 'tokens');
vals = cellfun(@str2double, vertcat(vals{:}));

И результат:

vals =

                   0   3.141600000000000   0.100000000000000  -0.100000000000000
   0.010000000000000   3.141600000000000   0.100000000000000  -0.100000000000000
   0.020000000000000   3.141600000000000   0.100000000000000  -0.100000000000000
   0.030000000000000   3.141600000000000   0.100000000000000  -0.100000000000000

Каждый столбец содержит значения для t, K, gamma и A.

1 голос
/ 11 июля 2019

Попробуйте это:

def to_cells(string):
strings = list(filter(None, string.split('u1 @ ')))
cells = {}

for cell in strings:
    pairs = cell.split(',')
    for pair in pairs:
        k, v = pair.split('=')
        k = k.strip()
        v = float(v)
        if k in cells:
            cells[k].append(v)
        else:
            cells[k] = [v]

return cells

Вы можете использовать функцию следующим образом:

res = to_cells(
    'u1 @ t=0, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.01, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.02, K=3.1416,'
    ' gamma=0.1, A=-0.1 u1 @ t=0.03, K=3.1416, gamma=0.1, A=-0.1'
)

for x in res:
    print(x, '\t====>\t', res[x])

И вывод будет выглядеть так:

t   ====>    [0.0, 0.01, 0.02, 0.03]
K   ====>    [3.1416, 3.1416, 3.1416, 3.1416]
gamma   ====>    [0.1, 0.1, 0.1, 0.1]
A   ====>    [-0.1, -0.1, -0.1, -0.1]

Надеюсь, это поможет:)

1 голос
/ 11 июля 2019

Без regex переменные сохраняются в виде чисел с плавающей точкой в ​​массиве 2D:

s = '''u1 @ t=0, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.01, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.02, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.03, K=3.1416, gamma=0.1, A=-0.1'''

out = []
for i in s.split('u1 @'):
    if not i.strip():
        continue
    out += [[float(v.split('=')[-1]) for v in i.split(',')]]

from pprint import pprint
pprint(out)

Печать:

[[0.0, 3.1416, 0.1, -0.1],
 [0.01, 3.1416, 0.1, -0.1],
 [0.02, 3.1416, 0.1, -0.1],
 [0.03, 3.1416, 0.1, -0.1]]
1 голос
/ 11 июля 2019

Вы можете разделить ваш текст с помощью re.split. Например, вы можете разделить каждый пробел, за которым следует «u1»:

import re
from pprint import pprint

text = 'u1 @ t=0, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.01, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.02, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.03, K=3.1416, gamma=0.1, A=-0.1'

lines = re.split(r'\s+(?=u1)', text)
pprint(lines)

Вы получаете:

['u1 @ t=0, K=3.1416, gamma=0.1, A=-0.1',
 'u1 @ t=0.01, K=3.1416, gamma=0.1, A=-0.1',
 'u1 @ t=0.02, K=3.1416, gamma=0.1, A=-0.1',
 'u1 @ t=0.03, K=3.1416, gamma=0.1, A=-0.1']

Затем можно проанализировать каждую строку этого результата, чтобы извлечь атрибуты:

for line in lines:
    attrs = {}
    for value in line[5:].split(", "):
        k, v = value.split("=")
        attrs[k] = float(v)
    print(attrs)

Вы получаете;

{'t': 0.0, 'K': 3.1416, 'gamma': 0.1, 'A': -0.1}
{'t': 0.01, 'K': 3.1416, 'gamma': 0.1, 'A': -0.1}
{'t': 0.02, 'K': 3.1416, 'gamma': 0.1, 'A': -0.1}
{'t': 0.03, 'K': 3.1416, 'gamma': 0.1, 'A': -0.1}
1 голос
/ 11 июля 2019

Вы можете использовать регулярные выражения.

Простое регулярное выражение для получения чисел: '-?\d*\.?\d*'.

Чтобы получить ваши данные, вы можете использовать это регулярное выражение.

'u1 @ t={0}, K={0}, gamma={0}, A={0}'.format('-?\d*\.?\d*')

Пример:

>>> import re
>>> text = 'u1 @ t=0, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.01, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.02, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.03, K=3.1416, gamma=0.1, A=-0.1'
>>> r = '-?\d*\.?\d*'
>>> re.findall('u1 @ t={0}, K={0}, gamma={0}, A={0}'.format(r), text)
['u1 @ t=0, K=3.1416, gamma=0.1, A=-0.1', 'u1 @ t=0.01, K=3.1416, gamma=0.1, A=-0.1', 'u1 @ t=0.02, K=3.1416, gamma=0.1, A=-0.1', 'u1 @ t=0.03, K=3.1416, gamma=0.1, A=-0.1']
0 голосов
/ 11 июля 2019

Я думаю, что это можно сделать проще без регулярных выражений в MATLAB. Использование строки вместо символа также помогает.

result = extractAfter(text,'u1 @ ');
result = split(result, 'u1 @ ');
result = split(result, ',');
result = extractAfter(result,'=');
result = double(result);

Возможно, это самое быстрое решение на данный момент.

>> testFunc
Elapsed time is 0.075453 seconds. % My solution
Elapsed time is 2.820094 seconds. % Luis Mendo solution

function testFunc()

    text = "u1 @ t=0, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.01, K=3.1416, " + ...
           "gamma=0.1, A=-0.1 u1 @ t=0.02, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.03, " + ...
           "K=3.1416, gamma=0.1, A=-0.1";

    % My solution
    tic
    for i = 1:1e4
        result = extractAfter(text,'u1 @ ');
        result = split(result, 'u1 @ ');
        result = split(result, ',');
        result = extractAfter(result,'=');
        result = double(result);
    end
    toc

    % Luis Mendo solution
    tic;
    for i = 1:1e4
        result = reshape(str2double(regexp(text + ' ', '(?<=(t|K|gamma|A)=).+?(?=,| )', 'match')), 4, [])';
    end
    toc
0 голосов
/ 11 июля 2019

Вот простой способ сделать это в MATLAB:

text ='u1 @ t=0, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.01, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.02, K=3.1416, gamma=0.1, A=-0.1 u1 @ t=0.03, K=3.1416, gamma=0.1, A=-0.1';
a=size(text);
pos1=strfind(text, 'u1'); % first position of variable
pos2=strfind(text, 'A='); % position of 'A='
pos2=pos2+5; % since after 'A=' there are five spaces until the end of the desired variable
vars=length(char); % number of new variables within 'text'
for i=1:length(pos2)
     output{i}=text(pos1(i):pos2(i)); % output variable as cell with entries as new variables
end 

Он находит положение первого и последнего символов требуемой переменной и удаляет их из «текста».Я бы порекомендовал следующий аналогичный метод для извлечения текста для отдельных имен и значений переменных.Для этого я бы использовал функцию «strfind» на знаке «=».

0 голосов
/ 11 июля 2019

Еще одно решение Matlab на основе регулярных выражений.Обозначение строки (символьного вектора) s,

v = reshape(str2double(regexp([s ' '], '(?<=(t|K|gamma|A)=).+?(?=,| )', 'match')), 4, []).';

дает, в вашем примере,

v =
                   0   3.141600000000000   0.100000000000000  -0.100000000000000
   0.010000000000000   3.141600000000000   0.100000000000000  -0.100000000000000
   0.020000000000000   3.141600000000000   0.100000000000000  -0.100000000000000
   0.030000000000000   3.141600000000000   0.100000000000000  -0.100000000000000

Регулярное выражение соответствует любому предшествующему t=, K= и т. д., а затем запятая или пробел.В конце строки добавляется пробел, чтобы можно было найти последнее совпадение.str2double преобразует совпавшую подстроку в число (если возможно).Затем некоторые операции транспонирования и изменения формы используются для упорядочения результатов в виде матрицы, где каждая из 4 переменных является столбцом.

...