После обновления pandas с 0.25.1 до 2.1.4 группировка по пользователю и заполнение по месяцам происходит намного медленнPython

Программы на Python
Anonymous
После обновления pandas с 0.25.1 до 2.1.4 группировка по пользователю и заполнение по месяцам происходит намного медленн

Сообщение Anonymous »

У меня есть ежемесячные данные в формате .csv общим объемом около 10 миллионов строк. Я создаю из него необходимый фрейм данных и заметил, что время выполнения для создания этого df увеличилось с примерно 20 минут до 8 часов с обновлением версии pandas с 0.25.1 до 2.1.4, поскольку я переустановил Anaconda. Это может иметь какое-либо отношение к обновлению панд, а может и не иметь, но проблема началась после обновления.
Для иллюстрации предположим, что у меня есть следующие 3 файла .csv за 26 января, 26 февраля, 26 марта.
26 января:

Код: Выделить всё

customer;user_id;user_name;status;user_type;last_login_timestamp;login_counter;month
1111;1;A;1;Normal;11.01.2026 11:38;100;202601
1111;2;B;1;Normal;04.01.2026 11:11;50;202601
2222;4;P;1;Normal;04.01.2026 21:16;40;202601
2222;5;Q;1;Admin;12.01.2026 04:54;55;202601
2222;6;R;1;Normal;23.01.2026 21:06;20;202601
3333;9;X;2;Normal;04.01.2026 06:56;70;202601
26 февраля:

Код: Выделить всё

customer;user_id;user_name;status;user_type;last_login_timestamp;login_counter;month
1111;1;A;1;Normal;21.02.2026 06:38;120;202602
2222;4;P;1;Normal;13.02.2026 18:11;50;202602
2222;5;Q;1;Admin;19.02.2026 14:51;60;202602
2222;6;R;1;Normal;11.02.2026 16:41;25;202602
26 марта:

Код: Выделить всё

customer;user_id;user_name;status;user_type;last_login_timestamp;login_counter;month
1111;1;A;1;Normal;05.03.2026 03:30;150;202603
1111;2;B;1;Normal;04.03.2026 21:51;60;202603
2222;4;P;1;Normal;12.03.2026 15:16;80;202603
2222;5;Q;1;Admin;24.03.2026 04:54;90;202603
2222;6;R;1;Normal;03.03.2026 21:06;45;202603
3333;9;X;2;Normal;21.03.2026 13:03;95;202603
Каждая строка соответствует определенному пользователю у клиента. Например, для клиента 1111 есть 2 пользователя 1 и 2. Если конкретный пользователь не заходил в систему в конкретном месяце, записи для него в этом месяце не будет. Например, пользователь 9 клиента 3333 не входил в систему 26 февраля, поэтому он отсутствует в данных.
В данных есть столбец login_counter, который подсчитывает количество раз, когда пользователь входил в систему. Теперь, если пользователь не заходил в систему в определенном месяце, счетчик_входа остается прежним. Таким образом, я хочу добавить строку для этого пользователя с тем же входным_счетчиком и последней_логинной_временной меткой из предыдущего/последнего месяца, когда был вход в систему.
Сначала я добавляю все файлы данных:

Код: Выделить всё

import pandas as pd
df_all = pd.DataFrame()

for i in ['Data_202601.csv', 'Data_202602.csv', 'Data_202603.csv']:
df = pd.read_csv(os.path.join(path, i), sep=';')
df['last_login_timestamp'] = pd.to_datetime(
df['last_login_timestamp'],
format='%d.%m.%Y %H:%M')
df['month'] = pd.to_datetime(df['month'], format='%Y%m')
df_all = df_all._append(df)
df_all = df_all.sort_values(
['customer', 'user_id', 'month'],
ascending=(True, True, True)
).reset_index(drop=True)
print(df_all)
Данные выглядят следующим образом:
Изображение

Следующий код добавляет отсутствующий месяц к данным за последний активный месяц:

Код: Выделить всё

df_all = (df_all.set_index('month')
.groupby(['customer', 'user_id'])
.apply(lambda x: x.asfreq('MS', method='ffill'))
.drop(['customer', 'user_id'], axis=1)).reset_index()
print(df_all)
Изображение

Теперь этот код стал ужасно медленным после обновления - с 20 минут до 8 часов
Как я могу ускорить выполнение до предыдущего времени выполнения?
Обновить: Бренден написал в своем ответе:
В качестве дополнительного бонуса я считаю, что это также исправило ошибку: данные за последний месяц не заполнялись вперед. Теперь это так!
Чтобы заполнить данные, мы должны указать месяц начала и месяц окончания, иначе они не будут заполнены. Например; предположим, у нас есть customer/user_id (4444/8), который появился в данных только от 26 января. Окончательные данные будут иметь только (4444/8) 26 января, потому что это начало и конец месяца. С подходом Брендена это не проблема, поскольку он заполняет данные за предыдущий месяц, и поскольку это делается для всех файлов (отсортированных по месяцам), таким образом, ничего не упускается. При его подходе customer/user_id (4444/8) появится 26 февраля и 26 марта с последними_login_timestamp и login_counter такими же, как и с 26 января.

Вернуться в «Python»