Получить максимальное значение третьего столбца после использования groupby над двумя столбцами

#python #pandas

#python #pandas

Вопрос:

У меня есть csv-файл с 3 столбцами (CustomerID, Description, UnitPrice). Я хочу получить самый ценный продукт (с максимальной ценой за единицу), который купил каждый клиент, и его цену.

Я загрузил базу данных отсюда:

https://archive.ics.uci.edu/ml/datasets/Online Retail

Я написал для этого код, и он работает, но, честно говоря, я не знаю, почему он работает, и это выглядит довольно глупо. Я хочу видеть в качестве конечного результата таблицу со всем деревом (CustomerID, Description и UnitPrice). Есть ли лучший способ сделать это:

 import pandas as pd

my_dataFrame = pd.read_csv("OnlineRetailNEW.csv", dtype={'CustomerID': object})

#the most valuable product that each customer bought, and its price
def get_most_valuable_product():

    most_valuable = my_dataFrame.groupby(["CustomerID", "Description"], sort=False)["UnitPrice"].max().reset_index()
    most_valuable = most_valuable.groupby(["CustomerID"]).max().reset_index()
    return most_valuable

print(get_most_valuable_product())
 

Я пробовал это, но это не дает мне хороших результатов:

 def get_most_valuable_product():

    most_valuable = my_dataFrame[["CustomerID", "Description", "UnitPrice"]].sort_values('UnitPrice').groupby(['CustomerID']).tail(1)
    return most_valuable

print(get_most_valuable_product())
 

Ответ №1:

 my_dataframe[[CustomerID, Description, UnitPrice]].sort_values('UnitPrice').groupby(['CustomerID']).tail(1)
 

Если мы отсортируем по цене единиц измерения, то groupby идентификатор, самый дорогой, всегда будет внизу каждой группы клиентов.

Комментарии:

1. Хорошо, но я хочу видеть только столбцы CustomerID, Description и UnitPrice

2. Это покажет вам их все, ооо, в вашем df есть еще столбцы, которые вы хотите скрыть? РЕДАКТИРОВАТЬ: изменил его, чтобы он отображал только эти три столбца.

3. Проблема в том, что это работает, но не дает правильного результата: most_valuable.groupby([«CustomerID»]).third_column_name.max()

4. Единственная причина, по которой я могу думать, что это не сработает, — это если у клиента есть 2 товара по одинаковой цене. Он бы случайным образом отсортировал их.

5. Я взял описание продукта из результата, нашел этот продукт в моем csv-файле, и цена единицы измерения не совпадает

Ответ №2:

Вы можете использовать most_valuable.groupby(["CustomerID"]).third_column_name.max()

Комментарии:

1. Это дало бы им только идентификатор клиента и максимальную цену. Однако им также нужно название продукта.

2. Это не то, чего я хочу. Я знаю, что могу это сделать, но я хочу видеть все 3 столбца в качестве выходных данных

Ответ №3:

Вы можете использовать idxmax

 maxids = my_dataFrame.groupby(['CustomerID', 'Description'].UnitPrice.idxmax()

my_dataFrame.loc(maxids.values)
 

Обратите внимание, что idxmax это дает вам только одну запись на группу. Если вам нужны все записи (несколько максимальных), затем используйте transform

 maxvals = my_dataFrame.groupby(['CustomerID', 'Description'].UnitPrice.transform(lambda x: x.max())

my_dataFrame[my_dataFrame.UnitPrice == maxvals]