Не могу задать индекс для создаваемого Pandas DateFrame

Имею следующие исходные данные:

# список столбцов
report_columns = ['Date', 'Result', 'Status', 'Count']
# создаём новый пустой DataFrame с использованием списка столбцов
report_df = pd.DataFrame(columns=report_columns)
# преобразуем первый столбец в datetime:
report_df[report_columns[0]] = pd.to_datetime(report_df[report_columns[0]])  # 'Date'
# остальные:
report_df[report_columns[1]] = report_df[report_columns[1]].astype(str)  # 'Result'
report_df[report_columns[2]] = report_df[report_columns[2]].astype(str)  # 'Status'
report_df[report_columns[3]] = report_df[report_columns[3]].astype(float)  # 'Count'

report_df = report_df.reset_index(drop=True)

def BuildReportItem(t_date, t_result, t_status, t_count):
    return {"Date": t_date, "Result": t_result, "Status": t_status, "Count": t_count}

for index, row in data_sience_csv.iterrows():
    .....
    check_signals = []
    .....
    if ...
        signal = BuildReportItem(row[0], s_compact, s_stat, iPointData)
        check_signals.append(signal)
    ....

    if check_signals != []:
        report_df = report_df.append(check_signals)
        print(report_df)

report_df.to_csv(csv_path2reports, sep=';')

В результате я получаю примерно следующее:

                 Date  Result  Status  Count
0 2020-03-12 13:00:00   Found    Warr    0.0
0 2020-06-03 11:00:00   Found      Ok   73.0

Как видно из вывода "индекс" почему-то всегда равен '0'! Хотя я понимаю, что скорее всего это даже и не индекс. Отсюда два вопроса

  1. Как указать индекс? Чтобы в первом столбце (который без имени) шли 0, 1, 2, 3 ... Т.е у DataFrame был числовой индекс, начинающийся с нуля.

  2. Можно ли в качестве индекса указать столбец 'Date'? Я это пробовал (через report_df.set_index), но результат увы такой же...


PS1:
На самом деле удивлён, что большинство сосредоточилось не на заданных мною вопросах, а на том как я заполняю DataFrame и откуда я получаю значения s_compact, s_stat, iPointData.. Хотя какая связь между этими вопросами и созданием пустого DataFrame, у которого почему-то не формируется index я так и не понял.. Ну да ладно, постараюсь ответить

  1. на тему iterrows - для меня скорость не критична, но если есть более скоростные решения буду признателен за рассказ о них (или за ссылку на пример кода).
  2. на тему s_compact, s_stat, iPointData - я даже не знаю что ответить.. Там кода обработки данных примерно на 400 строк (не считая вспомогательных функций) - его весь что-ли нужно приводить? Есть три функции, каждая из которых вызывает ещё несколько, которые обрабатывают фрейм из исходных данных (результаты работы двух медицинских приборов, выгруженные в CSV). Первая - если заданный критерий сработал, то возвращает строку, которая может иметь значения "Found" или "May be". Вторая возвращает строку, которая может иметь значения "Success", "Warr", "Info" и "Err". Третья - число, рассчитанное по определённому алгоритму. Чем это вам поможет - не знаю.

По-пробую ещё раз кратко описать задачу:

  1. Нужно создать пустой DateFrame, который в процессе выполнения алгоритма наполняется данными (подготовленными строками).
  2. Как установить индекс для пустого DateFrame? Я использовал report_df = report_df.set_index('Date') но такой вариант не срабатывает.. И можно ли сделать нумерацию не по дате, а просто - с нуля и до конца.

PS2: вопрос решился, спасибо @MaxU за подсказку!

Необходимо было после report_df = report_df.append(check_signals) добавить следующий код:

if (len(report_df) > 0):
    report_df = report_df.reset_index(drop=True)
    print(report_df)`

Тогда индекс в DataFrame отображается в виде целых чисел от 0 до N-1! Ещё раз спасибо! Не думал, что каждый раз, при добавлении строки, придётся reset_index делать!


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

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

Насколько я понимаю, пользователь хочет, чтобы у создаваемого им DataFrame был индекс. У самого была некоторое время назад такая же проблема, но решить не удалось и я забил на неё. Судя по приведённому результату в DataFrame не получается установить индекс почему-то. Я так понимаю, что автор хочет получить в 1 столбце индекс и чтобы была возможность сделать индекс в двух вариантах:

  1. Числовой - когда нумерация идёт с нуля: т.е 1 строка - 0, 2-ая - 1, 3-я -2 и т.д.
  2. Индекс по столбцу "Date".

P.S: ответ предыдущего автора не понятен

  1. Какая разница какие входные данные.. Из приведённого примера видно, что они формируются в программе, потом передаются в функцию BuildReportItem, которая возвращает dict, добавляемый в DataFrame
  2. И чем плох iterrows() если нужно перебрать все строки по одной?
→ Ссылка
Автор решения: MaxU

Вы используете очень неэффективные подходы:

  1. data_sience_csv.iterrows() - один из самых медленных и неэффективных способов работы с DataFrame
  2. Тоже самое можно сказать о добавлении по одной строке к DataFrame

По первому пункту:

Если вы поясните откуда и как вы получаете значения s_compact, s_stat, iPointData, то, наверняка, получите адекватный и идиоматический ответ.

Кроме того в вопросе следует приводить небольшие воспроизводимые примеры входных данных и то, что вы зотите получить в результате

По второму пункту:

В общем случае, можно собрать списки значений для каждого столбца и в конце создать DataFrame следующим образом:

df = pd.DataFrame({
    "Date": pd.to_datetime(list_of_date_strings),
    "Result": list_of_result_values,
    "Status": list_of_stats,
    "Count": pd.to_numeric(list_of_counts, errors="coerce")
})

Значения индекса тогда по умолчанию будут от 0 до N-1

Но, возможно, объяснив подробнее вашу задачу и приведя примеры входных и выходных данных, вам дадут более эффективный ответ.


UPD: чтобы установить индекс в DataFrame'е в виде целых чисел от 0 до N-1:

df = df.reset_index(drop=True)

PS эту операцию нужно делать после окончания заполнения DF! Делать это на пустом DataFrame - бессмысленно, т.к. в пустом DF нет ни строк ни значений индекса.

→ Ссылка