Когда я пытаюсь изменить форму, выдается сообщение об ошибке: «TypeError: списочные индексы должны быть целыми или кусочками, а не кортежем» - PullRequest
1 голос
/ 08 января 2020

На самом деле, я пытаюсь преобразовать код Matlab в python, и когда я пытаюсь изменить его форму, он выдает мне ошибку TypeError, говорящую: «Ошибка списка: индексы списка должны быть целыми или кусочками, а не кортежем».

Matlab

[file,path] = uigetfile('*.dwr');
fid = fopen(strcat(path,'/',file));
m5 = (fread(fid, '*uint8'));
m5=double(m5);
fclose(fid);
m6=m5(12514:end);
no_bin_ele=m5(12039:2:12218)+256*m5(12040:2:12218);
s1=size(m6);
s2=((no_bin_ele(1)*7+4)*360)*1;
n1=m6(1:s2);
j1=reshape(n1(1:end,1),no_bin_ele(1)*7+4,360*1);

Python

import numpy as np
with open('aa.dwr', 'rb') as fp:
m5 = np.fromstring(fp.read(), dtype='uint8')
m5 = m5.astype(float)
m5 = m5.tolist()
m6 = m5[12514:]
no_bin_ele = m5[12039:12218:2]+256*m5[12040:12218:2]
s1 = len(m6)
s2=((no_bin_ele[1]*7+4)*360)*1
s2 =int(s2)
n1=m6[1:s2]
j1 = np.reshape(n1[1: ,1], no_bin_ele[1]*7+4, 360*1)

Ошибка

Traceback (последний вызов был последним): файл "ppp.py", строка 26, в j1 = np.reshape (n1 [1:, 1], no_bin_ele [1] * 7 + 4, 360 * 1) TypeError: список индексов должны быть целыми числами или ломтиками, а не кортежем

Ответы [ 4 ]

1 голос
/ 09 января 2020

Проверка этой строки MATLAB:

no_bin_ele=m5(12039:2:12218)+256*m5(12040:2:12218);

В октаве я проверяю, что

12039:2:12218

производит 90 значений, 12039 до 12217.

12040:2:12218 

также производит 90, 12040 до 12218

Таким образом, строка принимает суммирующие последовательные пары, m5[i]+256*m5[i+1] Так как они были загружены как uint8, это дает, я думаю, значение uint16.

Но в numpy:

In [467]: np.arange(12039,12218,2).shape                                        
Out[467]: (90,)
In [468]: np.arange(12040,12218,2).shape                                        
Out[468]: (89,)

Конечная точка обработки отличается. Конечная точка 2-го среза должна быть 12219.

Это объясняет ошибку трансляции, когда m5 является массивом (который должен быть):

no_bin_ele = m5[12039:12218:2]+256*m5[12040:12218:2]

Преобразование m5 tolist() не помогает. Для списка * означает репликацию, а + означает объединение. Для массива это умножение и сложение. совершенно другой.

In [475]: alist = list(range(0,10))                                             
In [476]: alist                                                                 
Out[476]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [477]: alist[1:6:2] + 4*alist[2:6:2]                                         
Out[477]: [1, 3, 5, 2, 4, 2, 4, 2, 4, 2, 4]

Остальная часть кода работает со списком, потому что индексирование и нарезка одинаковы - вплоть до выражения n1[1: ,1]. Это действительно только для массива numpy.

На самом деле существуют другие проблемы с индексацией. Python Индексирование начинается с 0.

no_bin_ele(1)     # 1st element of the matlab matrix
no_bin_ele[0]     # 1st element of the array

n1(1:end,1)       # matlab matrix is 2d
n1[1: ,1]         # n1 isn't 2d
n1                # should just be

На самом деле я думаю, что последние несколько строк должны быть

s2=int(no_bin_ele[0]*7+4)*360)
n1=m6[:s2]
j1 = np.reshape(n1, (-1, 360))    # -1 stands in for no_bin_ele[0]*7+4

Хотя при таком изменении формы могут возникнуть order проблемы. MATLAB является главным столбцом, как order='F', с последним измерением в крайнем случае.

Я действительно хотел бы увидеть некоторые примеры данных для проверки шагов. Есть ограничения на то, что я могу вывести, просто читая код. Но я не интересуюсь обработкой данных длиной 12218 байт.

Опять же, образец Octave:

>> n1 = 1:10;
>> reshape(n1, 5,2)
ans =

    1    6
    2    7
    3    8
    4    9
    5   10

и numpy:

In [481]: n1 = np.arange(1,11)                                                  
In [482]: np.reshape(n1, (5,2))                                                 
Out[482]: 
array([[ 1,  2],
       [ 3,  4],
       [ 5,  6],
       [ 7,  8],
       [ 9, 10]])
In [483]: np.reshape(n1, (5,2),order='F')                                       
Out[483]: 
array([[ 1,  6],
       [ 2,  7],
       [ 3,  8],
       [ 4,  9],
       [ 5, 10]])
In [484]: np.reshape(n1, (2,5))                                                 
Out[484]: 
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])

===

m5 - это файл, читаемый как uint8, беззнаковые байты.

m6 - большая конечная часть, в которую мы хотим изменить форму (n, 360 ) матрица (или ее транспонирование).

no_bin_ele - более ранняя часть, которая, очевидно, состоит из 2-байтовых чисел, и мы используем первую из них, чтобы выбрать срез m6 для этого изменения формы.

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

1 голос
/ 08 января 2020

Python эквивалентный код. У меня нет доступа к 'aa.dwr', поэтому, пожалуйста, проверьте, равен ли j1, приходящий из matlab, j1, полученному из кода ниже.

import numpy as np
with open('aa.dwr', 'rb') as fp:
    m5 = np.fromstring(fp.read(), dtype='uint8')
    m5 = m5.astype(float)
    m5 = m5.tolist()
    m6 = m5[12513:]
    no_bin_ele = m5[12038:12219:2]+256*m5[12039:12219:2]
    s1 = len(m6)
    s2=((no_bin_ele[0]*7+4)*360)*1
    s2 =int(s2)
    n1=m6[:s2+1]
    j1 = np.reshape(n1[0: ,0], (no_bin_ele[0]*7+4, 360*1))
1 голос
/ 08 января 2020

Пожалуйста, попробуйте заключить в скобки второй и третий аргумент, сжимая его в 1:

j1 = np.reshape(n1[1: ,1], (no_bin_ele[1]*7+4, 360*1))

, как показано здесь: https://docs.scipy.org/doc/numpy/reference/generated/numpy.reshape.html Надеюсь, это поможет.

0 голосов
/ 08 января 2020

Это воспроизводит ваше сообщение об ошибке:

In [432]: [1,2,3][1:,1]                                                         
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-432-1613afcfe2a2> in <module>
----> 1 [1,2,3][1:,1]

TypeError: list indices must be integers or slices, not tuple

Это означает, что в

j1 = np.reshape(n1[1: ,1], no_bin_ele[1]*7+4, 360*1)

n1 есть список, где вы используете numpy индекс стиля массива.

Ошибки при попытке n1.shape имеют ту же проблему - список не имеет shape.

n1 происходит от m6, что происходит от m5, который приходит из tolist() метода!

В MATLAB все является MATRIX (за исключением ячеек и структуры). В Python списки самые близкие, но с добавлением numpy вы получаете массивы, которые больше похожи на MATLAB - за исключением того, что их число измерений может быть 0,1,2 и т.д. c. При отладке обратите внимание на переменные type, а если массив, shape и dtype.

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