2017-02-20 22 views
2

Я знаю, что если я хочу сохранить и загрузить массивы комплексных чисел с numpy, я могу использовать описанный здесь метод: How to save and load an array of complex numbers using numpy.savetxt?.Загрузка комплексных номеров с numpy.loadtxt

Предположим, однако, что кто-то не знает об этом и сохранили их массив numbers с numpy.savetxt("numbers.txt",numbers), для создания файла с записями вида

(0.000000000000000000e+00+-2.691033635430225765e-02j) . 

В этом случае

numbers_load = numpy.loadtxt("numbers.txt").view(complex) 

будет, предположительно, сбой в смысле

ValueError: could not convert string to float: (0.000000000000000000e+00+-2.691033635430225765e-02j) . 

Что такое wo uld - простой способ извлечения комплексных чисел из этого файла (без генерации другой версии)?

ответ

0

Перед сохранением массива, вы должны использовать .view(float), чтобы преобразовать его в массив float с, а затем .view(complex) конвертировать float сек назад complex чисел от нагрузки.

In [1]: import numpy as np 

In [2]: A = np.array([1+2j, 2+5j, 3-4j, -3+1j]) 

In [3]: A.view(float) 
Out[3]: array([ 1., 2., 2., 5., 3., -4., -3., 1.]) 

In [4]: np.savetxt("numbers.txt", A.view(float)) 

In [5]: np.loadtxt("numbers.txt") 
Out[5]: array([ 1., 2., 2., 5., 3., -4., -3., 1.]) 

In [6]: np.loadtxt("numbers.txt").view(complex) 
Out[6]: array([ 1.+2.j, 2.+5.j, 3.-4.j, -3.+1.j]) 
1

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

import numpy as np 
import re 

# a regular expression that picks out the two components of the complex number 
reg = re.compile('(-?\d.\d*e[+-]\d\d)\+(-?\d.\d*e[+-]\d\d)') 
# a function that returns a properly formatted string 
edit = lambda s: reg.search(s).expand(r'\1 \2') 

with open("numbers.txt", 'r') as fobj: 
    # calling map applies the edit function to each line of numbers.txt in turn 
    numbers_load = np.loadtxt(map(edit, fobj)) 
print(numbers_load) # [ 0.   -0.02691034] 
print(numbers_load.view('complex')) # [ 0.-0.02691034j] 
0

Документы для savetxt говорить о fmt опциях для комплексного массива.

Начиная с 1d массива:

In [17]: np.arange(5)+np.arange(5,0,-1)*1j 
Out[17]: array([ 0.+5.j, 1.+4.j, 2.+3.j, 3.+2.j, 4.+1.j]) 
In [18]: arr = np.arange(5)+np.arange(5,0,-1)*1j 

по умолчанию для записи чисел, один () строку в каждой строке. Чтение, что с loadtxt (или genfromtxt) будет проблемой. Он должен быть загружен как строка, а затем преобразован по строкам.

In [19]: np.savetxt('test.txt',arr) 
In [20]: cat test.txt 
(0.000000000000000000e+00+5.000000000000000000e+00j) 
(1.000000000000000000e+00+4.000000000000000000e+00j) 
(2.000000000000000000e+00+3.000000000000000000e+00j) 
(3.000000000000000000e+00+2.000000000000000000e+00j) 
(4.000000000000000000e+00+1.000000000000000000e+00j) 

В нем говорится, что я могу указать формат для реальной и мнимой частей, и в этом случае он сохраняет его как 2 столбца. Это легко читать с loadtxt.

In [21]: np.savetxt('test.txt',arr, fmt='%f %f') 
In [22]: cat test.txt 
0.000000 5.000000 
1.000000 4.000000 
2.000000 3.000000 
3.000000 2.000000 
4.000000 1.000000 

In [23]: np.loadtxt('test.txt') 
Out[23]: 
array([[ 0., 5.], 
     [ 1., 4.], 
     [ 2., 3.], 
     [ 3., 2.], 
     [ 4., 1.]]) 

In [25]: np.loadtxt('test.txt').view(complex) 
Out[25]: 
array([[ 0.+5.j], 
     [ 1.+4.j], 
     [ 2.+3.j], 
     [ 3.+2.j], 
     [ 4.+1.j]]) 

С 2d комплексного массивом Мне нужно указать FMT для всех столбцов

In [28]: arr1=np.array((arr, arr*.1, arr+1)) 
In [29]: arr1 
Out[29]: 
array([[ 0.0+5.j , 1.0+4.j , 2.0+3.j , 3.0+2.j , 4.0+1.j ], 
     [ 0.0+0.5j, 0.1+0.4j, 0.2+0.3j, 0.3+0.2j, 0.4+0.1j], 
     [ 1.0+5.j , 2.0+4.j , 3.0+3.j , 4.0+2.j , 5.0+1.j ]]) 

In [33]: np.savetxt('test.txt',arr1, fmt=['%f %f']*5) 
In [34]: cat test.txt 
0.000000 5.000000 1.000000 4.000000 2.000000 3.000000 3.000000 2.000000 4.000000 1.000000 
0.000000 0.500000 0.100000 0.400000 0.200000 0.300000 0.300000 0.200000 0.400000 0.100000 
1.000000 5.000000 2.000000 4.000000 3.000000 3.000000 4.000000 2.000000 5.000000 1.000000 
In [35]: np.loadtxt('test.txt').view(complex) 
Out[35]: 
array([[ 0.0+5.j , 1.0+4.j , 2.0+3.j , 3.0+2.j , 4.0+1.j ], 
     [ 0.0+0.5j, 0.1+0.4j, 0.2+0.3j, 0.3+0.2j, 0.4+0.1j], 
     [ 1.0+5.j , 2.0+4.j , 3.0+3.j , 4.0+2.j , 5.0+1.j ]]) 

Документов показывают длинную строку формата со всеми столбцами, но, видимо, список строк работает

In [36]: ['%f %f']*5 
Out[36]: ['%f %f', '%f %f', '%f %f', '%f %f', '%f %f'] 

savetxt присоединяется к этому списку с разделителем, чтобы сделать одну длинную строку формата.

In [37]: np.savetxt('test.txt',arr1, fmt=['%f %f']*5, delimiter=',') 
In [38]: cat test.txt 
0.000000 5.000000,1.000000 4.000000,2.000000 3.000000,3.000000 2.000000,4.000000 1.000000 
... 

Для loadtxt разделителем между сложными частями и столбцов должен быть совместим:

In [39]: np.savetxt('test.txt',arr1, fmt=['%f %f']*5, delimiter=' ') 
In [40]: cat test.txt 
0.000000 5.000000 1.000000 4.000000 2.000000 3.000000 3.000000 2.000000 4.000000 1.000000 
... 

В целом, сохранение/загрузка поездка туда и обратно будет проще всего, если save делается с нагрузкой совместимых форматов.

1

Вы можете использовать converters для обработки пользовательского формата. Единственная проблема, которая предотвращает правильное считывание сложного значения, - +- в 1+-2j, заменив их на 1-2j.

>>> numpy.savetxt('1.txt', numpy.array([2.3+4.5j, 6.7-0.89j])) 

>>> numpy.loadtxt('1.txt', dtype=complex) # <- doesn't work directly 
ValueError: complex() arg is a malformed string 

>>> numpy.loadtxt('1.txt', dtype=complex, converters={0: lambda s: complex(s.decode().replace('+-', '-'))}) 
array([ 2.3+4.5j , 6.7-0.89j]) 

 Смежные вопросы

  • Нет связанных вопросов^_^