Создайте массив numpy из матрицы, объявленной в файле .m matlab - PullRequest
2 голосов
/ 28 октября 2011

Сотрудник оставил некоторые файлы данных, которые я хочу проанализировать с помощью Numpy.

Каждый файл представляет собой файл Matlab, скажем data.m, и имеет следующее форматирование (но с гораздо большим количеством столбцов и строк):

values = [-24.92 -23.66 -22.55 ;
-24.77 -23.56 -22.45 ;
-24.54 -23.64 -22.56 ;
];

, который является типичным явным синтаксисом создания матриц, используемым matlab.

Мой вопрос: какой самый практичный способ создать массив из этих файлов?

Я мог бы подумать о "грубой силе" или "быстром и грязном" решении, но если бы было более простое решение, я бы предпочел использовать его, как стандартную функцию из numpy или даже из другого модуля.

РЕДАКТИРОВАТЬ: я заметил, что мои файлы могут содержать значения NaN, поэтому я, скорее всего, буду адаптировать ответы для использования numpy.genfromtxt вместо numpy.loadtxt.Я планирую включить свой окончательный код, как только он у меня появится.

Спасибо за любую помощь!

РЕДАКТИРОВАТЬ: я получил следующий код, где я получаю все в диапазоне от [], используяregex, и создайте массив numpy, используя genfromtxt для обработки NaN.Более коротким решением может быть использование метода fromstring, для которого не требуется StringIO, но он не может обработать NaN, а мои данные имеют NaN: oP

#!/usr/bin/env python
# coding: utf-8

import numpy, re, StringIO

with open('data.m') as f:
    s = re.search('\[(.*)\]', f.read(), re.DOTALL).group(1)
    buf = StringIO.StringIO(s)
    a = numpy.genfromtxt(buf, missing_values='NaN', filling_values=numpy.nan)

Ответы [ 2 ]

2 голосов
/ 28 октября 2011

Вот несколько вариантов, хотя ни один из них не встроен.

Решение, которое вы, вероятно, не найдете приемлемым

Это решение, вероятно, относится к вашей категории "быстрых и грязных", но онопомогает привести к следующему решению.

Удалите values = [, последнюю строку (];) и глобально замените все ; ничем, чтобы получить:

-24.92 -23.66 -22.55 
-24.77 -23.56 -22.45 
-24.54 -23.64 -22.56 

Затем вы можете использовать loadtxt numpy следующим образом.

>>> import numpy as np
>>> A = np.loadtxt('data.m')

>>> A
array([[-24.92, -23.66, -22.55],
       [-24.77, -23.56, -22.45],
       [-24.54, -23.64, -22.56]])

Решение, которое вы можете найти приемлемым

. В этом решении мы создаем метод для приведения входных данных в форму, которая numpyloadtxt лайков (на самом деле в той же форме, что и выше).

import StringIO
import numpy as np

def convert_m(fname):
    with open(fname, 'r') as fin:
        arrstr = fin.read()
    arrstr = arrstr.split('[', 1)[-1] # remove the content up to the first '['
    arrstr = arrstr.rsplit(']', 1)[0] # remove the content after ']'
    arrstr = arrstr.replace(';', '\n') # replace ';' with newline
    return StringIO.StringIO(arrstr)

Теперь, когда у нас это есть, сделайте следующее.

>>> np.loadtxt(convert_m('data.m'))
array([[-24.92, -23.66, -22.55],
       [-24.77, -23.56, -22.45],
       [-24.54, -23.64, -22.56]])
1 голос
/ 28 октября 2011

Вы можете передать итератор на np.genfromtxt:

import numpy as np
import re

with open(filename, 'r') as f:
    lines = (re.sub(r'[^-+.0-9 ]+', '', line) for line in f)
    arr = np.genfromtxt(lines)

print(arr)

выходы

[[-24.92 -23.66 -22.55]
 [-24.77 -23.56 -22.45]
 [-24.54 -23.64 -22.56]]

Спасибо Bitwise за подсказку к этому ответу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...