Преобразовать строку из файла в массив

У меня есть файл с примерно таким содержимым

[[ 1.26328700e-01 -8.60362032e-02  1.08476497e-02 -1.04204727e-01
  -1.92207606e-02 -5.39169052e-03 -9.63348960e-02 -1.98400576e-02
   2.01329727e-02  4.73981229e-02]
 [ 8.02003808e-02 -1.09610489e-02  3.02463242e-02  1.32122119e-01
   1.31999639e-01 -4.75952046e-02  1.02049774e-01  2.15685271e-02
   6.42994605e-02 -7.74405584e-02]
 [ 1.28561995e-01  7.95866773e-02 -1.15243032e-01  1.92310916e-02
   1.14984214e-01 -1.16455947e-01  1.10658362e-01  5.93929971e-02
  -5.28909913e-02 -1.06716183e-01]]

Как открыть содержимое и преобразовать его в numpy массив?


Ответы (3 шт):

Автор решения: ganz

Для хранения массивов нумпай рекомендую использовать модуль h5py, который разработан каким-то универом, специально для чего-то

import h5py
file=h5py.File('file/h5py.hdf5','a')
file.keys()
#<KeysViewHDF5 ['dset', 'dset02', 'link_group', 'subgroup']>
file.name
#/
file.filename
#h5py.hdf5 r+
file.mode
#r+

#grp = file.create_group("subgroup")
group=file['subgroup']
file['link_group'] = h5py.ExternalLink("file/h5py.hdf5", "subgroup")
file['subgroup'].visit(print)
#data
file.move('link_group','link_group2')
del file['link_group2']
group.name
#/subgroup 
group.file
#<HDF5 file "h5py.hdf5" (mode r+)> 
group.parent
#<HDF5 group "/" (3 members)>
→ Ссылка
Автор решения: strawdog

В общем, как тут было отмечено, хранение массивов numpy в таком формате - очень неудачное решение. Но, если у вас безвыходная ситуация, то решить ее можно так (опять же, код зависит от размерности исходного массива):

import numpy as np
import re

def make_array(a: str)-> np.array:
    with open("myfile.txt", "r") as  f:
        a = "".join(f.read().splitlines())
        res = np.array([np.fromstring(x, dtype=float, sep=' ') for x in re.findall(r"\[([^\[\]]+)\]", a)])
        return res
    
arrays = make_array("myfile.txt")

ну и теперь проверяем:

print(arrays)
print(type(arrays))
[[ 0.1263287  -0.0860362   0.01084765 -0.10420473 -0.01922076 -0.00539169
  -0.0963349  -0.01984006  0.02013297  0.04739812]
 [ 0.08020038 -0.01096105  0.03024632  0.13212212  0.13199964 -0.0475952
   0.10204977  0.02156853  0.06429946 -0.07744056]
 [ 0.128562    0.07958668 -0.11524303  0.01923109  0.11498421 -0.11645595
   0.11065836  0.059393   -0.05289099 -0.10671618]]
<class 'numpy.ndarray'>
→ Ссылка
Автор решения: М. Абдул

Вроде так не будет зависеть от размерности, но код вышел побольше и замороченее

def get_numpy_array(text):
    import numpy, re

    def get_brackets(text : str, brackets = "[]"):
        output = [[],[]]
        while 1:
            brackets_i = [text.find(i) for i in brackets]
            norm_brackets = list(filter(lambda x: x != -1, brackets_i))
            if len(norm_brackets) == 0:
                break
            first_bracket = min(norm_brackets)
            offset = output[0][-1]+1 if len(output[0]) > 0 else 0
            output[0].append(offset+first_bracket)
            output[1].append(brackets[brackets_i.index(first_bracket)])
            text = text[first_bracket+1:]
        return output

    def try_func(n_str : str, func):
        try:
            func(n_str)
            return True
        except:
            return False

    def fill_array(text : str, arr : list, brackets : list, func = lambda x: x, iter = 0):
        while len(brackets[0][iter:]) > 1:
            start,end = brackets[0][iter:iter+2]
            if brackets[1][iter] == '[':
                arr.append([])
                tf = func(text[start:end])
                if len(tf) != 0: 
                    arr[-1].extend(tf)
                if brackets[1][iter+1] == '[':
                    iter = fill_array(text, arr[-1], brackets, func, iter+1)
                    continue
                elif brackets[1][iter+1] == ']':
                    iter+=1
            elif brackets[1][iter] == ']':
                return iter+1
            iter+=1
        return iter

    to_float = lambda x: list(map(float, filter(lambda x: try_func(x, float), re.split(" |\n", x))))

    arr = []
    fill_array(text, arr, get_brackets(text, "[]"), to_float)
    return numpy.array(arr[0])

Далее вызываем функцию и передаем содержимое файла:

with open("file.txt","r") as f:
    print(get_numpy_array(f.read()))
→ Ссылка