Доступ к значению ячейки pandas с помощью df.itertuples() и имени столбца дает ошибку атрибута

#python #pandas #dataframe #loops

Вопрос:

У меня есть следующий фрейм данных, из которого я хочу извлечь значения ячеек, используя имена индексов и столбцов. В левом столбце указаны значения индекса, в то время как имена столбцов находятся в диапазоне от 1 до 5. Это фиктивный фрейм данных, который выглядит небольшим, но в дальнейшем я буду использовать этот код для доступа к фрейму данных со 100 столбцами, и заранее узнать имена столбцов невозможно.

1 2 3 4 5
t_1 1 0 0 0 1
t_2 1 1 0 0 0
t_3 1 0 0 0 0
t_4 1 0 1 0 1

Чтобы извлечь значения из этого фрейма данных, я использую itertuples() цикл to для фрейма данных pandas. Пожалуйста, обратите внимание, что с помощью iterrows() этого можно легко сделать, но это намного медленнее, из-за чего я хочу избежать этого. Вот фрагмент кода для итерации фрейма данных:

 for row in input_df.itertuples():  print(row.Index)  for col in input_df.columns[1:]:  print(row.col)  

Поскольку я не буду знать имена столбцов заранее, я хочу получить имена столбцов из списка фреймов данных, а затем использовать его для извлечения значений ячеек. Например, t_1 столбец строки 1 должен возвращать значение 1. Однако с помощью приведенного выше кода я получаю следующую ошибку:

 AttributeError: 'Pandas' object has no attribute 'col'  

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

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

1. Может быть, вы имели в виду row[col] ?

2. @Ритуальное использование print(getattr(row, col)) вместо print(row.col) . Вы также можете использовать print(input_df.loc[row.Index, col])

3. @HenryEcker Я попробовал это, но там говорилось, что индекс строки должен быть int, а не str.

4. Спасибо @aberry, ваши решения сработали идеально! Не могли бы вы, пожалуйста, подсказать, какой из этих двух: getattr, loc будет быстрее?

5. зачем вам нужно перебирать свой фрейм данных?

Ответ №1:

Просто измените row.col на getattr(row, col) :

 for row in input_df.itertuples():  print(row.Index)  for col in input_df.columns[1:]:  print(getattr(row, col))  

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

1. Это приводит к следующей ошибке: TypeError: tuple indices must be integers or slices, not str мои фактические имена столбцов являются строковыми.

2. О, я понимаю почему. Вы используете itertuples по какой-то конкретной причине? Вы могли бы повторить более просто.

3. Извините, я ошибся. Я не понял этого itertuples звонка. Я отредактировал ответ; теперь он должен сработать для вас. Однако, если ваши столбцы являются числами, это не сработает, потому itertuples что автоматически префиксирует столбцы, начинающиеся с цифры с подчеркиванием, поэтому вызываемый столбец 1 будет переименован _1 в возвращаемые кортежи itertuples .

4. Я использую итерации для более быстрого решения, так как в будущем я буду иметь дело с большим фреймом данных. Спасибо, что объяснили мне это о getattr. решение @aberry отлично работает в этом сценарии.

5. Спасибо @user17242583! 🙂