0

Как исправить ошибку IndexError: недопустимый индекс для скалярной переменной

9

Вопрос на 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 ответ(ов)

0

Вы пытаетесь индексировать скалярное (неитерируемое) значение:

[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, и подкорректируйте код соответственно.

0

Вы правы! В вашем коде есть возможность упростить доступ к именам слоев, убрав лишнюю индексацию. Вместо того чтобы использовать i[0] - 1, можно просто использовать i - 1. Это делает код более читаемым. Вот исправленный код:

layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]

Такой подход работает и более очевиден, так как getUnconnectedOutLayers() возвращает индексы слоев напрямую. Спасибо за ваше замечание! Это действительно улучшает понимание кода.

0

На 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. Убедитесь, что вы используете правильный подход в зависимости от вашей версии интерпретатора.

0

В принципе, 1 не является допустимым индексом для y. Если посетитель обращается к этому в своем коде, он должен проверить, содержит ли y индекс, к которому он пытается получить доступ (в данном случае индекс 1).

0

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

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь