Как задать имя переменной используя конкатенацию: строковое значение + порядковый номер? (Например, имя df_1 получается как "df_" + str(i), где i = 1)

Цель такая: прочитать методом pandas.read_excel некоторое количество файлов, всегда разное, и "склеить" их, нарастив их содержимое одно под другим. Вот как выглядит мой код сейчас:

import pandas as pd
# читаем
df_01 = pd.read_excel('Результаты 1_01.07.22 - 07.07.22.xlsx', header=3)
df_02 = pd.read_excel('Результаты 1_08.07.22 - 14.07.22.xlsx', header=3)
df_03 = pd.read_excel('Результаты 1_17.06.22 - 23.06.22.xlsx', header=3)
df_04 = pd.read_excel('Результаты 1_24.06.22 - 30.06.22.xlsx', header=3)
df_05 = pd.read_excel('Результаты 2_01.07.22 - 07.07.22.xlsx', header=3)
df_06 = pd.read_excel('Результаты 2_08.07.22 - 14.07.22.xlsx', header=3)
df_07 = pd.read_excel('Результаты 2_17.06.22 - 23.06.22.xlsx', header=3)
df_08 = pd.read_excel('Результаты 2_24.06.22 - 30.06.22.xlsx', header=3)
df_09 = pd.read_excel('Результаты 3_01.07.22 - 07.07.22.xlsx', header=3)
df_10 = pd.read_excel('Результаты 3_08.07.22 - 14.07.22.xlsx', header=3)
df_11 = pd.read_excel('Результаты 3_17.06.22 - 23.06.22.xlsx', header=3)
df_12 = pd.read_excel('Результаты 3_24.06.22 - 30.06.22.xlsx', header=3)
# склеиваем
df = (
    df_01
    .append(df_02)
    .append(df_03)
    .append(df_04)
    .append(df_05)
    .append(df_06)
    .append(df_07)
    .append(df_08)
    .append(df_09)
    .append(df_10)
    .append(df_11)
    .append(df_12)
)

Файлы всегда стандартные, с одинаковым количеством столбцов и с шапкой одной высоты, поэтому хочется завернуть процедуру чтения файлов в функцию, которая бы сама генерировала имена переменных по шаблону "df_" + str(i). Как это сделать и возможно ли такое?


Ответы (2 шт):

Автор решения: mrEvgenX

Лучше сделать как-то так. Используя списки и цикл for и по алгоритму "прочитал/приклеил/повторил".

import pandas as pd
# читаем
df = pd.read_excel('file_0.xlsx', header=3)
file_names = [
    'file_1.xlsx',
    # ...
]
for file_name in file_names:
    df = df.append(pd.read_excel(file_name, header=3))
→ Ссылка
Автор решения: Василий Балин

Так, я немного прокачал свои навыки и могу сказать, как не надо, по мнению уважаемых гуру, да и не только. За комментарии сильно не пинайте, мне с ними помогал ChatGPT:

import glob  # Импортируем модуль glob для работы с файловыми путями и поиска файлов по шаблону.

import pandas as pd  # Импортируем библиотеку pandas для работы с данными.

# Инициализируем пустой DataFrame, в который будем добавлять данные из всех прочитанных файлов.
df = pd.DataFrame()

# Цикл для прохода по диапазону от 1 до max_i (предполагается,
# что max_i определен ранее и равен количеству файлов,
# которые мы объединяем).
for i in range(1, max_i + 1):
    # Создаем имя переменной в формате 'df_01', 'df_02', и т.д.,
    # используя метод zfill для дополнения номера до двух цифр.
    # В случае, когда файлов более 99, нужно менять 2 на 3 и т.д., 
    # в зависимости от количества значащих разрядов
    df_name = f'df_{str(i).zfill(2)}'
    
    # Используем glob для поиска файлов, которые соответствуют заданному шаблону.
    # В шаблоне используются '?' для подстановки любых символов (например, дата и время).
    filename = glob.glob(r'.\Результаты ?_??.??.?? - ??.??.??.xlsx')[i]
    
    # Читаем данные из найденного файла в DataFrame, начиная с четвертой строки (header=3).
    # Имя переменной DataFrame создается динамически с помощью exec и формируется на основе df_name.
    # Это может привести к потенциальным проблемам с безопасностью и отладкой кода.
    exec(rf'{df_name} = pd.read_excel("{filename}", header=3)')
    
    # Объединяем текущий DataFrame с главным DataFrame (df) с помощью pd.concat.
    # Снова используем exec для динамической ссылки на имя переменной.
    # Опция ignore_index=True используется для игнорирования индексов
    # и создания нового непрерывного индекса.
    exec(f'df = pd.concat([df, {df_name}], ignore_index=True)')

Пояснения: Модуль glob: Используется для поиска файлов, соответствующих заданному шаблону, в данном случае шаблон включает символы ?, которые заменяют любые символы (чаще всего используется для даты и времени).

Создание переменных динамически: df_name формируется на основе номера итерации цикла i, который заполняется нулями слева до двух цифр (например, '01', '02').

Использование exec: Это функция Python, которая выполняет строку как код Python. В данном случае используется для динамического создания переменных и выполнения операций. Это может быть небезопасно и сложно для отладки, особенно если строки формируются на основе входных данных.

Объединение DataFrames: Используется функция pd.concat для объединения всех DataFrame в один, игнорируя оригинальные индексы и создавая новый непрерывный индекс.

→ Ссылка