Преобразовать матрицу строк в NumPy - PullRequest
0 голосов
/ 08 ноября 2019

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

[[[1.65 0.53 0 1][0.99 1.41 0 1][0.38 1.37 0 1][0 0 1 1][1.10 0.69 0 1][0 0 1 1][0.60 1.21 0 1][0.99 1.04 0 1][1.86 1.20 0 1][0 0 1 1][1.66 0.68 0 1][0.96 0.75 0 1][0.86 0.80 0 1][1.13 0.97 0 1][1.86 1.48 0 1][0 0 1 1][0.71 1.10 0 1][1.43 0.58 0 1][1.34 0.63 0 1][1.37 1.45 0 1][0.36 1.08 0 1][0 0 1 1][0.60 1.18 0 1][1.08 0.64 0 1][0.99 0.58 0 1][1.57 1.16 0 1][0.87 1.39 0 1][0.48 1.21 0 1][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0]][[1.52 1.01 0 1][0.93 0.62 0 1][1.41 0.52 0 1][1.66 0.83 0 1][0 0 1 1][1.02 1.03 0 1][0.98 0.92 0 1][0 0 1 1][0.65 0.90 0 1][0 0 1 1][1.27 0.61 0 1][0.41 0.79 0 1][1.23 1.04 0 1][0.56 0.70 0 1][0 0 1 1][1.81 0.90 0 1][0 0 1 1][1.71 0.57 0 1][1.53 1.06 0 1][1.28 1.42 0 1][1.50 0.91 0 1][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0]][[0 0 1 1][0.53 1.17 0 1][0.24 0.54 0 1][1.88 0.68 0 1][0 0 1 1][1.33 0.68 0 1][0.32 0.55 0 1][1.28 0.73 0 1][0.49 1.13 0 1][1.45 1.28 0 1][0.66 1.47 0 1][0 0 1 1][0.76 1.10 0 1][1.95 0.78 0 1][0 0 1 1][0.56 0.61 0 1][0.84 1.05 0 1][1.07 0.59 0 1][1.79 0.95 0 1][1.93 1.02 0 1][1.93 1.16 0 1][0 0 1 1][0.55 0.58 0 1][0.29 1.13 0 1][1.46 0.50 0 1][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0]][[1.71 0.50 0 1][0.70 1.35 0 1][0 0 1 1][0.90 0.83 0 1][1.81 0.97 0 1][1.64 1.35 0 1][1.21 1.15 0 1][0.54 0.50 0 1][0 0 1 1][0.62 0.72 0 1][0.86 1.38 0 1][0 0 1 1][1.76 1.15 0 1][1.83 1.43 0 1][0.20 0.51 0 1][0.81 0.65 0 1][0 0 1 1][0.51 0.79 0 1][1.09 1.43 0 1][1.65 1.03 0 1][1.47 1.49 0 1][0 0 1 1][1.57 0.97 0 1][0.99 0.93 0 1][1.82 0.66 0 1][1.84 1.01 0 1][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0]][[0 0 1 1][1.36 0.94 0 1][1.61 0.64 0 1][0.99 1.03 0 1][1.43 1.12 0 1][1.09 1.16 0 1][0.40 1.40 0 1][0 0 1 1][0.86 0.56 0 1][0.54 0.80 0 1][0.77 1.04 0 1][0 0 1 1][1.38 0.61 0 1][0.37 1.38 0 1][1.12 1.28 0 1][0 0 1 1][1.87 0.67 0 1][1.75 0.52 0 1][0.31 0.52 0 1][0.99 0.88 0 1][0 0 1 1][1.38 1.30 0 1][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0][0 0 0 0]]]

Как я могу преобразовать это в форму NumPy? Этот ответ предлагает использовать fromstring;однако в документации говорится, что это работает только для одномерных матриц.

Ответы [ 3 ]

2 голосов
/ 08 ноября 2019

Зависит от того, если это уже list, вы можете просто использовать np.array() для прямого преобразования, если это строка, вам, вероятно, сначала нужно вставить ,, чтобы сделать ее допустимым списком Python. Вот пример, если это строка

import ast
import numpy as np

myString = "<YOUR STRING ABOVE>"
myString = myString.replace(" ", ",") # Replace [0 0 0 0] with [0,0,0,0]
myString = myString.replace("][", "],[") # Replace [0,0,0,0][0,0,0,0] with [0,0,0,0],[0,0,0,0] 
myList = ast.literal_eval(s) # Turn string into a list
myArr = np.array(myList) # Turn list into np_array

Надеюсь, это поможет, если ваши данные уже являются списком, вы можете просто перейти прямо к np.array(myList)

Размеры массива Iсозданный из данных выше:

myArr.shape
(5, 33, 4)

Редактировать: Изменил eval () на ast.literal_eval в соответствии с предложением @ b_c

0 голосов
/ 08 ноября 2019

Я закончил с этим:

import ast
import numpy as np

def StringToMatrix(txtmat):
    txtmat = txtmat.replace(" ",",").replace("][","],[")
    try:
        ret = np.array(ast.literal_eval(txtmat))
    except:
        ret = None
    return ret
0 голосов
/ 08 ноября 2019

Без разрывов строк это совсем не "красиво".

Я думаю, что самый быстрый способ - использовать поиск / замену регулярных выражений, чтобы добавить , между разделенными пробелами цифрами и между][. это, однако, не будет очень умным и сломается в угловых случаях (например, числа, оканчивающиеся на .), поэтому вам, возможно, придется настроить идею:

Теперь, попробовав это здесь, старыйвысказывание еще раз подтверждает правильность: «если у вас есть одна проблема, требующая регулярных выражений, у вас есть две проблемы» (неизвестный автор).

Проблема в том, что некоторые числа состоят из одной цифры, когда это число совпадает с запятой для числа перед ним, механизм регулярных выражений не может сопоставить его до числа после it.

Итак, нам нужно идтипосле «просмотра матчей вперед» и «просмотра матчей» с использованием синтаксиса (?=...), который позволяет сопоставить только то место, куда мы хотим добавить «,».

после этого у вас есть строка, гдеВы можете использовать "eval", чтобы иметь структуру вложенного списка, которая может быть передана непосредственно в numpy.array.

import numpy as np
import re
from ast import literal_eval

b = re.sub(r"((?<=\d)\s+(?=\d)|(?<=\])\s*?(?=\[))", ", " , a) 
c = np.array(literal_eval(b))

Конечно, если у вас всегда есть один пробел между числами и без пробелов или разрывов между "] [", простая замена строки без регулярных выражений будет намного проще. Используйте регулярные выражения, если у вас есть свободные пробелы во входных данных.

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