Как исправить ошибку IndexError: недопустимый индекс для скалярной переменной
Вопрос на StackOverflow:
Я сталкиваюсь с ошибкой при выполнении следующего кода:
IndexError: invalid index to scalar variable.
Ошибка возникает на строке:
results.append(RMSPE(np.expm1(y_train[testcv]), [y[1] for y in y_test]))
Вот полный код:
import pandas as pd
import numpy as np
from sklearn import ensemble
from sklearn import cross_validation
def ToWeight(y):
w = np.zeros(y.shape, dtype=float)
ind = y != 0
w[ind] = 1./(y[ind]**2)
return w
def RMSPE(y, yhat):
w = ToWeight(y)
rmspe = np.sqrt(np.mean( w * (y - yhat)**2 ))
return rmspe
forest = ensemble.RandomForestRegressor(n_estimators=10, min_samples_split=2, n_jobs=-1)
print ("Cross validations")
cv = cross_validation.KFold(len(train), n_folds=5)
results = []
for traincv, testcv in cv:
y_test = np.expm1(forest.fit(X_train[traincv], y_train[traincv]).predict(X_train[testcv]))
results.append(RMSPE(np.expm1(y_train[testcv]), [y[1] for y in y_test]))
Переменная testcv
имеет следующий вид:
[False False False ..., True True True]
Как исправить эту ошибку?
Любая подсказка будет очень полезной! Спасибо!
5 ответ(ов)
Вы пытаетесь индексировать скалярное (неитерируемое) значение:
[y[1] for y in y_test]
# ^ это и есть проблема
Когда вы вызываете [y for y in test]
, вы уже итерируете по значениям, и в y
оказывается единственное значение.
Ваш код эквивалентен следующему:
y_test = [1, 2, 3]
y = y_test[0] # y = 1
print(y[0]) # эта строка вызовет ошибку
Не совсем понятно, что именно вы хотите получить в массиве результатов, но вам необходимо избавиться от выражения [y[1] for y in y_test]
.
Если вы хотите добавить каждое значение из y_test
в массив results
, вам нужно расширить ваше выражение с列表推导,以如下方式:
[results.append(..., y) for y in y_test]
Или просто используйте цикл:
for y in y_test:
results.append(..., y)
Проверьте, что вы делаете с элементами в y_test
, и подкорректируйте код соответственно.
Вы правы! В вашем коде есть возможность упростить доступ к именам слоев, убрав лишнюю индексацию. Вместо того чтобы использовать i[0] - 1
, можно просто использовать i - 1
. Это делает код более читаемым. Вот исправленный код:
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
Такой подход работает и более очевиден, так как getUnconnectedOutLayers()
возвращает индексы слоев напрямую. Спасибо за ваше замечание! Это действительно улучшает понимание кода.
На StackOverflow вопрос по теме детекции объектов с использованием YOLO может выглядеть так:
Вопрос:
Как получить названия слоев в YOLO при использовании различных версий Python?
Я использую библиотеку OpenCV для работы с YOLO, и мне нужно получить названия слоев. Обратите внимание, что я использую версию Python ниже 3.7 и выше 3.7.
Вот код для Python ⇐ 3.7:
ln = net.getLayerNames()
ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]
А вот код для Python > 3.7:
ln = net.getLayerNames()
ln = [ln[i - 1] for i in net.getUnconnectedOutLayers()]
Может кто-то объяснить разницу между этими двумя подходами и как правильно использовать их?
Ответ:
Разница между двумя подходами заключается в том, как метод getUnconnectedOutLayers()
возвращает информацию о слоях в зависимости от версии Python.
В версиях Python 3.7 и ниже возвращаемое значение getUnconnectedOutLayers()
- это массив массивов, где каждый элемент является массивом с одним числом. Поэтому, чтобы получить индекс слоя, вам нужно использовать i[0]
.
Для Python 3.7 и выше getUnconnectedOutLayers()
возвращает одномерный массив индексов, что позволяет напрямую обращаться к элементам с помощью i
.
Таким образом, если вы используете Python ⇐ 3.7:
ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]
А если у вас версия Python > 3.7, то достаточно:
ln = [ln[i - 1] for i in net.getUnconnectedOutLayers()]
Эти две строки кода выполняют одну и ту же задачу, просто с учетом различий в структуре возвращаемых данных между версиями Python. Убедитесь, что вы используете правильный подход в зависимости от вашей версии интерпретатора.
В принципе, 1
не является допустимым индексом для y
. Если посетитель обращается к этому в своем коде, он должен проверить, содержит ли y
индекс, к которому он пытается получить доступ (в данном случае индекс 1
).
В вашем цикле for
происходит итерация, и для каждого элемента этого цикла, который, вероятно, является скалярным значением, индекс не применяется. Когда каждый элемент представляет собой пустой массив, одну переменную или скаляр, а не список или массив, использование индексов невозможно. Поэтому убедитесь, что вы работаете с массивом или списком, если хотите использовать индексацию.
Создание нового столбца на основе значений других столбцов / Применение функции к нескольким столбцам построчно в Pandas
Преобразование DataFrame Pandas в массив NumPy
Pandas read_csv: Опции low_memory и dtype
Различие между типами str и object в Pandas
Построение гистограммы на логарифмической шкале с помощью Matplotlib