get_dummies ошибка памяти Python

У меня проблема с набором данных, который имеет 400 000 строк и 300 переменных. Я должен получить фиктивные переменные для категориальной переменной с 3000+ различных предметов. В конце я хочу получить набор данных с 3300 переменными или функциями, чтобы я мог тренировать модель RandomForest.

Вот что я пытался сделать:

 df = pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_')], axis=1)

Когда я делаю это, я всегда получаю ошибку памяти. Есть ли ограничение на количество переменных, которые я могу иметь?

Если я сделаю это только с первыми 1000 строками (которые получили 374 разных категории), то это будет нормально работать.

У кого-нибудь есть решение моей проблемы? Компьютер, который я использую, имеет 8 ГБ памяти.

12 голосов | спросил Duesentrieb 9 J000000Thursday15 2015, 18:27:48

1 ответ


0

Обновление: Начиная с версии 0.19.0, get_dummies возвращает 8-битное целое число, а не 64-битное с плавающей точкой, что во многих случаях решит эту проблему и создаст as_type ниже решение не нужно. См. get_dummies - pandas 0.19.0

Но в других случаях описанная ниже опция sparse может оказаться полезной.

Оригинальный ответ: Вот несколько вариантов, которые можно попробовать. И то, и другое существенно сократит объем памяти в кадре, но вы все равно можете столкнуться с проблемами памяти позже. Трудно предсказать, вам просто нужно попробовать.

(обратите внимание, что я упрощаю вывод info() ниже)

df = pd.DataFrame({ 'itemID': np.random.randint(1,4,100) })

pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_')], axis=1).info()

itemID       100 non-null int32
itemID__1    100 non-null float64
itemID__2    100 non-null float64
itemID__3    100 non-null float64

memory usage: 3.5 KB

Вот наша базовая линия. Каждый фиктивный столбец занимает 800 байт, поскольку в примере данных содержится 100 строк, а get_dummies по умолчанию имеет значение float64 (8 байт). Это кажется излишне неэффективным способом хранения манекенов, поскольку вы можете использовать его всего лишь немного, но для этого может быть какая-то причина, о которой я не знаю.

Итак, с первой попытки, просто замените однобайтовое целое число (похоже, это не вариант для get_dummies должно быть выполнено как преобразование с помощью astype(np.int8).

pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_').astype(np.int8)], 
                              axis=1).info()

itemID       100 non-null int32
itemID__1    100 non-null int8
itemID__2    100 non-null int8
itemID__3    100 non-null int8

memory usage: 1.5 KB

Каждый фиктивный столбец теперь занимает 1/8 памяти, как и раньше.

Кроме того, вы можете использовать опцию sparse в get_dummies

pd.concat([df, pd.get_dummies(df['itemID'],prefix = 'itemID_',sparse=True)], 
                              axis=1).info()

itemID       100 non-null int32
itemID__1    100 non-null float64
itemID__2    100 non-null float64
itemID__3    100 non-null float64

memory usage: 2.0 KB

Довольно сопоставимая экономия. Вывод info() несколько скрывает способ экономии, но вы можете посмотреть на значение использования памяти, чтобы увидеть общую экономию.

Что из этого будет лучше работать на практике, будет зависеть от ваших данных, поэтому вам просто нужно дать каждому попробовать (или вы даже можете объединить их).

ответил JohnE 9 J000000Thursday15 2015, 20:08:58

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132