2015-09-22 1 views
1

Мои поля DataFrame 3 - это учетная запись, месяц и зарплата.Pandas groupby + преобразование, принимающее часы за 600 миллионов записей

account month    Salary 
1  201501    10000 
2  201506    20000 
2  201506    20000 
3  201508    30000 
3  201508    30000 
3  201506    10000 
3  201506    10000 
3  201506    10000 
3  201506    10000 

Я делаю groupby на счете и в месяц и рассчитывая сумму зарплаты для группы. Затем удалите дубликаты.

MyDataFrame['salary'] = MyDataFrame.groupby(['account'], ['month'])['salary'].transform(sum) 
MyDataFrame = MyDataFrame.drop_duplicates() 

Ожидая выход, как показано ниже:

account month    Salary 
1  201501    10000 
2  201506    40000 
3  201508    60000 
3  201506    40000 

Это хорошо работает для нескольких записей. Я пробовал то же самое за 600 миллионов записей, и он продолжается с 4-5 часов. Первоначально, когда я загружал данные, используя данные pd.read_csv(), полученные в 60 ГБ ОЗУ, до 1-2 часов использования ОЗУ было от 90 до 120 ГБ. Через 3 часа процесс занимает 236 ГБ оперативной памяти, и он все еще работает.

Просьба предложить, если для этого имеется другой альтернативный более быстрый способ.

EDIT:. Сейчас 15 минут в df.groupby ([ 'счет', 'месяц'], вроде = False) [ 'зарплата'] сумма()

+2

Не следует утверждение просто: 'df.groupby ([ 'счет', 'месяц']) Salary.sum()'.? – Alexander

+0

@Alexander Я сейчас пытаюсь это сделать, не уверен, что оба они разные – Vipin

+0

@Alexander У меня возникла ошибка «Несовместимый индекс вставленных столбцов с индексом кадра», я запускаю его как MyDataFrame ['pay'] = MyDataFrame.groupby ([ account '], [' month ']) [' pay ']. sum() – Vipin

ответ

2

Просто следить за ответом chrisb и комментарий Александра, вы действительно получите больше производительности из .sum() и .agg('sum') методов. Вот Jupyter %%timeit выход для трех:

Timeit results on groupby methods

Таким образом, ответы на которые chrisb и Александр Упоминание примерно в два раза быстро на очень небольшой пример набора данных.

Кроме того, согласно Pandas API documentation, добавление kwarg sort=False также поможет выполнить работу. Итак, ваша группа должна выглядеть примерно как df.groupby(['account', 'month'], sort=False)['Salary'].sum(). Действительно, когда я его запускал, он был примерно на 10% быстрее, чем прогоны, показанные на приведенном выше изображении.

+0

все ответы были действительно полезны, выбрав его из-за sort = False – Vipin

2

, если я не недоразумение что-то , вы действительно делаете aggregation - transform предназначен для тех случаев, когда вам нужны данные в форме в качестве исходного кадра. Это должно быть несколько быстрее и делать все за один шаг.

df.groupby(['account', 'month'])['Salary'].agg('sum') 
+0

Я попробую это и дам вам знать результат – Vipin

2

Возможно, стоит загрузить версию для разработки Pandas 0.17.0. Они разблокируют GIL, который контролирует многопоточность. Это будет изначально реализовано в группе, и в этом блоге предлагается увеличить скорость на 3 раза по сравнению с групповым примером.

http://continuum.io/blog/pandas-releasing-the-gil

http://pandas.pydata.org/

+0

Это действительно хорошая функция, я попробую это. – Vipin

+0

дайте мне знать, что это работает! – AZhao

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