Отбор строк датасета по нескольким условиям Python
На вход дан датасет, где id - id пользователя, url - просмотренная страница, timestamp - время просмотра страница.
id url timestamp
0 a page_1 2021-10-09 15:46:20
1 a page_2 2021-10-09 15:47:20
2 a page_3 2021-10-09 15:48:20
3 a page_4 2021-10-09 15:49:20
4 a page_2 2021-10-09 15:50:20
5 b page_4 2021-10-09 15:18:20
6 b page_3 2021-10-09 15:21:20
7 b page_2 2021-10-09 15:22:20
8 b page_1 2021-10-09 15:24:20
9 b page_1 2021-10-09 15:26:20
Каждый из пользователей гарантированно посещает page_2. Необходимо выбрать все, посещенные каждым из пользователем страницы, до page_2. Если пользователь несколько раз посещал page_2, то необходимо включить все страница до последнего посещения page_2. Оригинальный массив очень большой, поэтому хотелось бы найти способ более быстрый чем перебор. Заранее спасибо
Ответы (1 шт):
Моё решение будет работать только если ваши данные будут иметь следующий формат (называется csv):
# файл input.csv
id,url,timestamp
a,page_1,2021-10-09 15:46:20
a,page_2,2021-10-09 15:47:20
a,page_3,2021-10-09 15:48:20
a,page_4,2021-10-09 15:49:20
a,page_2,2021-10-09 15:50:20
b,page_4,2021-10-09 15:18:20
b,page_3,2021-10-09 15:21:20
b,page_2,2021-10-09 15:22:20
b,page_1,2021-10-09 15:24:20
b,page_1,2021-10-09 15:26:20
Решение:
import pandas as pd
def all_visited_pages_until(page, user_id, df):
df_by_user = df[(df.id == user_id)]
df_by_user = df_by_user.sort_values(by="timestamp")
last_row_index_by_page = df_by_user.url.where(df_by_user.url == page).last_valid_index()
return df_by_user.loc[:last_row_index_by_page]
def main():
df = pd.read_csv("input.csv", sep=",")
print(all_visited_pages_until("page_2", "a", df))
if __name__ == '__main__':
main()
Вывод программы:
0 page_1
1 page_2
2 page_3
3 page_4
4 page_2
Name: url, dtype: object
На выходе получили объект Series. Если будет необходимо, его можно будет преобразовать в list
===UPD===
Если все страницы имеют вид page_i (i это соответственно номер), то для оптимизации хранения большого объёма данных можно вместо page_i хранить именно i.
Для этого перед вызовом функции all_visited_pages_until достаточно написать df.url = df.url.apply(lambda url: int(url.replace("page_", "")))