Pandas перечисляет все уникальные значения на основе группировки

У меня есть фрейм данных, содержащий информацию о рабочем сайте.

District#    Site#           Address
        1        1    123 Bayview Ln
        1        2    456 Example St
        2       36      789 Hello Dr
        2       44      789 Hello Dr

Я пытаюсь преобразовать этот фрейм данных, чтобы добавить столбец с самым высоким номером сайта, а также отдельные адреса при группировке по номеру района. Вот пример того, как я хочу, чтобы результат выглядел:

District#    Site#           Address    MaxSite#            All District Addresses
        1        1    123 Bayview Ln           2     123 Bayview Ln,456 Example St
        1        2    456 Example St           2     123 Bayview Ln,456 Example St
        2       36      789 Hello Dr          44                      789 Hello Dr
        2       44      789 Hello Dr          44                      789 Hello Dr

Я могу получить Max Site#, выполнив

df['MaxSite#'] = df.groupby(by='District#')['Site#'].transform('max')

Но я пытаюсь найти аналогичный способ составить список всех уникальных адресов при группировке по номеру округа.

Я пробовал выполнить .transform('unique'), но это недопустимое имя функции, и выполнение .agg(['unique']) возвращает несовпадающие размеры.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
51
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы можете использовать groupby и agg, чтобы получить максимальный номер сайта и перечислить все адреса.

Затем merge вернёмся к исходному фрейму данных:

grouped_df = df.groupby('District#').agg(Max_Site_Num=('Site#', 'max'), 
      All_District_Addresses=('Address', lambda x: list(set(x))).reset_index()

df = df.merge(grouped_df,on='District#')

Выход:

     District#  Site#         Address  Max_Site_Num            All_District_Addresses
0          1      1  123 Bayview Ln             2  [123 Bayview Ln, 456 Example St]
1          1      2  456 Example St             2  [123 Bayview Ln, 456 Example St]
2          2     36    789 Hello Dr            44                    [789 Hello Dr]
3          2     44    789 Hello Dr            44                    [789 Hello Dr]

Чтобы получить уникальные адреса, нужно выполнить два шага.

  1. Мы получаем уникальные адреса, соответствующие каждому District#, и объединяем их в одну строку.
  2. Затем мы создаем серию All District Addresses, сопоставляя District# с unique_addresses DataFrame.
data = {
 "District#": [1, 1, 2, 2],
 "Site#": [1, 2, 36, 44],
 "Address": ["123 Bayview Ln", "456 Example St", "789 Hello Dr", "789 Hello Dr"]
}
df = pd.DataFrame(data)
# Series you already calculated
df['MaxSite#'] = df.groupby(by='District#')['Site#'].transform('max') 

# Adding per-district unique addresses 
unique_addresses = df.groupby(by = "District#")["Address"].unique().apply(lambda x: ",".join(x))  # to make values a single string
df["All District Addresses"] = df["District#"].map(unique_addresses)

Выход:

   District#  Site#         Address  MaxSite#         All District Addresses
0          1      1  123 Bayview Ln         2  123 Bayview Ln,456 Example St
1          1      2  456 Example St         2  123 Bayview Ln,456 Example St
2          2     36    789 Hello Dr        44                   789 Hello Dr
3          2     44    789 Hello Dr        44                   789 Hello Dr

Однострочник, если вы предпочитаете:

df["All District Addresses"] = df["District#"].map(df.groupby(by = "District#")["Address"].unique().apply(lambda x: ",".join(x)))

Используя transform:

df["Max_Site_Num"] = df.groupby("District#")["Site#"].transform("max")
df["All_District_Addresses"] = df.groupby("District#")["Address"].transform(
    lambda x: ",".join(set(x))
)
   District#  Site#         Address  Max_Site_Num         All_District_Addresses
0          1      1  123 Bayview Ln             2  456 Example St,123 Bayview Ln
1          1      2  456 Example St             2  456 Example St,123 Bayview Ln
2          2     36    789 Hello Dr            44                   789 Hello Dr
3          2     44    789 Hello Dr            44                   789 Hello Dr

Другие вопросы по теме