#python #pandas #dataframe #data-science
#питон #панды #фрейм данных #наука о данных
Вопрос:
Входные данные, история транзакций в файлах JSON:
{"customer_id": "C1", "basket": [{"product_id": "P3", "price": 506}, {"product_id": "P4", "price": 121}], "date_of_purchase": "2018-09-01 11:09:00"} {"customer_id": "C27", "basket": [{"product_id": "P57", "price": 154}, {"product_id": "P42", "price": 349}, {"product_id": "P47", "price": 180}], "date_of_purchase": "2021-09-06 04:52:08.505909"} {"customer_id": "C1", "basket": [{"product_id": "P3", "price": 506}, {"product_id": "P4", "price": 121}], "date_of_purchase": "2018-10-01 11:09:00"}
Фрейм данных:
customer_id basket date_of_purchase 0 C4 [{'product_id': 'P31', 'price': 26}] 2021-09-06 05:47:08.505909 1 C13 [{'product_id': 'P36', 'price': 566}] 2021-09-06 03:52:08.505909 2 C15 [{'product_id': 'P02', 'price': 839}] 2021-09-06 05:48:08.505909 3 C22 [{'product_id': 'P37', 'price': 1235}] 2021-09-05 20:52:08.505909 4 C27 [{'product_id': 'P57', 'price': 154}, {'produc... 2021-09-06 04:52:08.505909
Мой код для считывания JSON в фрейм данных:
def read_json_folder(json_folder: str): transactions_files = glob.glob("{}*/*.json".format(json_folder)) return pandas.concat(pandas.read_json(tf, lines=True) for tf in transactions_files)
Для каждой транзакции мне нужен идентификатор клиента и количество раз, когда они покупали определенный продукт.
Ожидаемый результат:
customer_id product_id purchase_count C1 P2 11 C1 P3 5 C2 P9 7
Комментарии:
1. У вас уже есть JSON в фрейме данных?
2. @user17242583 да, это уже есть в кадре данных.
3. Как ты его туда протащил? вот так?
pd.json_normalize(j, record_path='basket', meta='customer_id')
(гдеj
находится список объектов json)
Ответ №1:
- Создайте фрейм данных из данных
- read_json с аргументом строк
- разнесите список корзин по строкам корзины
- разложите информацию о продукте по идентификаторам продуктов и ценам
- отбросьте ненужные столбцы
- Построить результирующий кадр данных из df
- группбай и граф
- переименуйте столбец «количество»
gt;gt;gt;TESTDATA=""" ...{"customer_id": "C1", "basket": [{"product_id": "P3", "price": 506}, {"product_id": "P4", "price": 121}], "date_of_purchase": "2018-09-01 11:09:00"} ...{"customer_id": "C27", "basket": [{"product_id": "P57", "price": 154}, {"product_id": "P42", "price": 349}, {"product_id": "P47", "price": 180}], "date_of_purchase": "2021-09-06 04:52:08.505909"} ...{"customer_id": "C1", "basket": [{"product_id": "P3", "price": 506}, {"product_id": "P4", "price": 121}], "date_of_purchase": "2018-10-01 11:09:00"} ...""" gt;gt;gt;df = pd.read_json(TESTDATA, lines=True) gt;gt;gt;df = df.explode('basket') gt;gt;gt;df[['product_id', 'price']] = df['basket'].apply(pd.Series) gt;gt;gt;df.drop(['basket', 'price'], axis=1, inplace=True) gt;gt;gt;df2 = df.groupby(['customer_id', 'product_id'], as_index=False).count() gt;gt;gt;df2.rename(columns={'date_of_purchase': 'purchase_count'}, inplace=True) gt;gt;gt;df2 customer_id product_id purchase_count 0 C1 P3 2 1 C1 P4 2 2 C27 P42 1 3 C27 P47 1 4 C27 P57 1
Комментарии:
1. третий столбец должен быть purchase_count, а не date_of_purchase
2. @Casper2210 , я добавил строку для переименования
Ответ №2:
Если ваш фрейм данных будет таким:
shop_list = [ {"customer_id": "C1", "basket": [{"product_id": "P3", "price": 506}, {"product_id": "P4", "price": 121}], "date_of_purchase": "2018-09-01 11:09:00"}, {"customer_id": "C27", "basket": [{"product_id": "P57", "price": 154}, {"product_id": "P42", "price": 349}, {"product_id": "P47", "price": 180}], "date_of_purchase": "2021-09-06 04:52:08.505909"}, {"customer_id": "C1", "basket": [{"product_id": "P3", "price": 506}, {"product_id": "P4", "price": 121}], "date_of_purchase": "2018-10-01 11:09:00"} ] shop = pd.DataFrame(shop_list)
давайте сначала получим все товарные позиции для каждого клиента
customer_groupby = shop.groupby('customer_id')['basket'].apply(list).to_dict() for k in customer_groupby.keys(): customer_groupby[k] = [item['product_id'] for sublist in customer_groupby[k] for item in sublist] output: #{'C1': ['P3', 'P4', 'P3', 'P4'], 'C27': ['P57', 'P42', 'P47']}
затем создайте таблицу результатов:
table= pd.DataFrame(columns=['customer_id', 'product_id', 'purchase_count']) for customer,value in customer_groupby.items(): items = set(value) for item in items: table= table.append({'customer_id':customer, 'product_id':item, 'purchase_count':value.count(item)}, ignore_index=True)
конечный результат:
Комментарии:
1. Отвечает ли это решение на ваш вопрос?@ Каспер2210
Ответ №3:
Попробуйте это:
purchase_counts = df.groupby(['customer_id', 'product_id'], as_index=False).count()
Выход:
gt;gt;gt; purchase_counts customer_id product_id price 0 C1 P3 2 1 C1 P4 2 2 C27 P42 1 3 C27 P47 1 4 C27 P57 1
Комментарии:
1. Если мой код не работает для вас, не могли бы вы добавить пример того, как выглядит ваш фрейм данных, к вопросу?