Являются ли целочисленные типы Pandas с нулевым значением плохими для производительности по сравнению с float

#python #pandas #performance #data-cleaning

#python #pandas #Производительность #очистка данных

Вопрос:

Я новичок в науке о данных, я пытался выполнить некоторую очистку данных, и у меня был столбец лет в моем фрейме данных. Предположительно, год должен быть целым числом, но, поскольку есть некоторые значения NA, он автоматически обозначается как float . Интересно, лучше ли преобразовать его в nullable int like pd.Int32Dtype() или оставить его плавающим. Есть ли какая-либо разница с точки зрения производительности?

Ответ №1:

Я построил два основных примера, оба с одинаковыми данными. Я создал a DataFrame из 1-мерного массива размером 500 000. Я также присвоил None нескольким элементам массива.

Построение данных:

 import time
import pandas as pd

years = [i for i in range(0, 500000)]
years[23] = None
years[44] = None
years[151] = None
  

Int:

 start = time.perf_counter()

df_int = pd.DataFrame(data = years, dtype = pd.Int32Dtype())

finish = time.perf_counter()
print(f'Finished in {finish-start}')


# Finished in 0.17838970199999993
  

Float:

 start = time.perf_counter()

df_float = pd.DataFrame(data = years)

finish = time.perf_counter()
print(f'Finished in {finish-start}')


# Finished in 0.07671123900000004
  

Из выходных данных преобразование данных в pd.Int32Dtype() явно медленнее.

Однако время, необходимое для представления этого массива из 500 000 элементов Int32Dtype , все еще было очень быстрым для большого массива. Это очень простой пример, поскольку в реальных данных будет намного больше столбцов, вложенных массивов и т. Д. Это особенно верно для науки о данных, поскольку наборы данных машинного обучения могут быть чрезвычайно большими и многомерными.

Редактировать:

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

Я настроил скрипт, который усредняет время, затраченное на удаление недостающих значений и сброс индекса фрейма данных. Усреднение было выполнено с использованием времени из 200 запусков. Размер массива остается таким же, как и раньше: 500 000. На этот раз отличается то, что я сделал каждое значение, которое равномерно делится на 200 None . Это означает None , что в этом массиве 2500 отображений.

 years = [None if i%200 == 0 else i for i in range(0, 500000)]
  

Int:

 times = []
for i in range(0,200):
    df_int = pd.DataFrame(data = years, dtype = pd.Int32Dtype(), columns=['years'])

    start = time.perf_counter()
    df_int.dropna(inplace=True)
    df_int.reset_index(drop=True, inplace=True)
    finish = time.perf_counter()

    times.append((finish-start))
  

Float:

 times = []
for i in range(0,200):
    df_float = pd.DataFrame(data = years, columns=['years'])

    start = time.perf_counter()
    df_float.dropna(inplace=True)
    df_float.reset_index(drop=True, inplace=True)
    finish = time.perf_counter()

    times.append((finish-start))
  

Средние значения были взяты следующим образом:

 avg = sum(times)/len(times)
  

Результаты были следующими:

 # Float: 0.009853112889999979
# Int:   0.009194320404999973
  

Ресурсы:

Работа с отсутствующими данными

Целочисленный тип данных с нулевым значением

pandas.DataFrame.fillna

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

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