Python напечатает значение списка, но скажет, что список пуст при попытке доступа к значениям (с помощью .pop() или индексирования[0] и т.д.)

#python #pandas #list #xlsx

Вопрос:

Фон

Я читаю данные из электронной таблицы .xlsx, используя Pandas 1.3.4 и Python 3.9.6.

Мне нужны данные для каждого элемента на основе a code в столбце «Код», поэтому я сначала изолирую строку в фрейме данных ( df ), используя:

 row = df.loc[df['Code'] == code]
 

Чтобы затем получить отдельные значения в строке, я обращаюсь к ним с помощью индексации и их заголовков следующим образом:

 barcode = row['Barcode'].values.tolist()
 

Я использую .values , так как в противном случае получаю громоздкий номер строки и вывод типа данных. Я использую .tolist() это для того, чтобы я мог эффективно получить доступ к фактическому штрих-коду, а не к научной интерпретации обозначений. Обратите внимание, что это означает barcode , что должен быть список с одним значением.

Проблема

Вот моя проблема, когда я печатаю barcode , я получаю разумный вывод, например: [72934728491] (обратите внимание, что это не настоящий штрих-код, а пример 11 цифр)

Обновление: len(barcode) возвращает 1 и type(barcode) возвращает <class 'numpy.ndarray'> или <class 'list'> , если я использовал .tolist()

Однако, если я попытаюсь получить доступ к значению внутри списка с помощью barcode[0] или barcode.pop() я получу ошибки, говорящие о том, что индекс находится вне диапазона или что .pop() его нельзя использовать в пустом списке.

Странно, но если я напишу цикл for, чтобы получить значение из списка, это будет работать просто отлично:

 for item in barcode:
    print(item)
 

Вопрос

Пожалуйста, может ли кто-нибудь объяснить, почему это происходит и как это на самом деле исправить (вместо того, чтобы писать цикл for для каждого значения столбца, к которому мне нужно получить доступ в строке).

Обновление (больше кода по запросу)

Я попытался создать минимальный жизнеспособный пример, чтобы помочь, но сейчас изо всех сил пытаюсь воспроизвести проблему в другом коде, это раздел, в котором я анализирую фрейм данных, к сожалению, я не могу показать раздел, в котором я читаю в df, поскольку он содержит личную информацию, но электронная таблица считывается в df «нормально».:

 for code in new_items:
    row = df.loc[df['Code'] == code] # row for a single item code
    product_display_name = row['Product Display Name'].values
    product_type = row['Product Type'].values
    description = row['Description'].values
    artist = row['Artist'].values
    barcode = row['Barcode'].values.tolist()
    finish = row['Finish'].values
    unit = row['Unit'].values
    country_of_origin = row['Country of Origin'].values
    job_number = row['Job No.'].values
    samples_date = row['Samples Date'].values

print(barcode.pop()) # this does not work
for item in barcode:
    print(item) # this does work
 

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

1. Похоже, ваша библиотека переопределяет вещи таким образом, которого вы не ожидаете. Я мало что знаю о пандах, но вы можете распечатать(ввести(штрих-код)), чтобы начать поиск документации по этому классу.

2. Попробуй: barcode = row['Barcode'].astype(str).values.tolist()

3. Не могли бы вы, пожалуйста, показать весь свой код?

4. type(barcode) это list для меня — @HmmmCurious твоя проблема для меня потеряна…

5. Спасибо за предложение @Corralien, я пробовал, но у меня все та же проблема с пустым списком. type(barcode) это <class 'numpy.ndarray'> для меня, пока я не изменю его на список, используя .tolist() . Я обновлю свой вопрос, чтобы показать больше моего кода в соответствии с просьбой.

Ответ №1:

Проблема оказалась связана с обработкой пандами NaN значений пустых ячеек.

В то время как отображаются NaN кадры данных , где-то в процессе .values .tolist() преобразования и я терял эту информацию и имел пустые массивы. Это было еще более осложнено каким-то странным форматированием электронной таблицы, которое означало, что в кадре данных была 0-я строка всех NaN значений, поэтому мой цикл даже не достиг допустимого значения до сбоя.