Страницы

Поиск по вопросам

понедельник, 19 ноября 2018 г.

Массив целых чисел: TypeError: only length-1 arrays can be converted to Python scalars

import scipy import scipy.fftpack import cmath import math import matplotlib.pyplot as plt import numpy as np from scipy import signal from scipy.signal import freqs, iirfilter xx = np.linspace(0, 1024, 1024) # диапазон значений x byts = ([0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1]) ff = 64 # %Частота несущей ns = np.sin(2 * np.pi * (x - 1) * ff / 1024) # несущая y = ns * byts[round(int(x + 31) / 64)] # %сигнал plt.plot(y)
Ошибка:
TypeError: only length-1 arrays can be converted to Python scalars
Как правильно нужно задать массив целых чисел х, чтобы не возникало данной ошибки?


Ответ

Разберёмся, почему возникает данная ошибка. Посмотрим на выражение:
round(int(x + 31) / 64)
x + 31 это массив длины 1024, а мы его приводим к int'у и непонятно, что должно получиться в результате. Python так и говорит:
TypeError: только массивы длины один могут быть приведены к скалярному типу (int это скалярный тип)
Уберём приведение к int'у:
y = ns * byts[round((x + 31) / 64)]
Ошибка пропадёт, но появится другая:
TypeError: type numpy.ndarray doesn't define __round__ method
Можно заменить round на np.round
y = ns * byts[np.round((x + 31) / 64)]
Мы получим другую ошибку
TypeError: only integer scalar arrays can be converted to a scalar index
Дело в том, что np.round((x + 31) / 64) это массив, с типом элементов float, а мы используем этот массив как массив индексов, а индексы могут быть только целыми. Нужно изменить тип элементов массива с помощью astype
y = ns * byts[np.round((x + 31) / 64).astype(int)]
Мы опять получим другую ошибку
TypeError: only integer scalar arrays can be converted to a scalar index
Дело в том, что byts это обычный массив, и через квадратные скобки нельзя обращаться с массивом индексов. Сделаем byts numpy-массивом:
byts = np.array([0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1])
Наша следующая ошибка
IndexError: index 16 is out of bounds for axis 1 with size 16
Возникает из-за того, что в конце массива np.round((x + 31) / 64 есть элементы, равные 16. Возможным решением будет изменение типа элементов массива x на int
x = np.linspace(0, 1023, 1024).astype(int)
и замена сложного выражения np.round((x + 31) / 64 на простое x // 64
y = ns * byts[x // 64] # %сигнал
Итоговый код:
import scipy import scipy.fftpack import cmath import math import matplotlib.pyplot as plt import numpy as np from scipy import signal from scipy.signal import freqs, iirfilter x = np.linspace(0, 1023, 1024).astype(int) # диапазон значений x byts = np.array([0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1]) ff = 64 # %Частота несущей ns = np.sin(2 * np.pi * (x - 1) * ff / 1024) # несущая y = ns * byts[x // 64] # %сигнал plt.plot(y)

Комментариев нет:

Отправить комментарий