2015-07-09 3 views
7

i relativly new для Python, и у меня есть небольшая проблема с набором данных. Набор данных содержит 400 000 строк и 300 переменных. Я должен получить фиктивные переменные для категориальной переменной с 3000 + разными элементами. В конце я хочу получить набор данных с 3300 переменными или функциями, чтобы я мог обучать модель RandomForest.get_dummies ошибка памяти python

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

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

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

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

У кого-нибудь есть решение для моей проблемы?

Машина, которую я использую, представляет собой Intel I7 с 8 ГБ RAM.

Спасибо

+0

32-разрядный или 64-разрядный Python? Пределом является размер кучи реализации Python, который является областью виртуальной памяти, а не ОЗУ. Различные версии и различные реализации в разных операционных системах имеют разные ограничения.Очевидно, вы ударили один. Вы должны хранить все эти данные в виртуальной памяти одновременно? – cdarke

+0

Я использую 64-битный Python. Каким будет решение? Что я разделяю набор данных на несколько частей и выполняю свою операцию на этих разных частях? – Duesentrieb

+0

ОК, я собирался предположить, что если бы вы были на 32-битной. В этом случае вам нужно пересмотреть свой дизайн. – cdarke

ответ

18

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

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

(обратите внимание, что я упрощая вывод 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() несколько скрывает способ экономии средств, но вы можете посмотреть на ценность использования памяти, чтобы увидеть общую экономию.

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

+0

Большое спасибо. Я изменил тип данных на целое, и он работает! – Duesentrieb

Смежные вопросы