Панды: получить первое вхождение и игнорировать, если в любом другом столбце в тот же день

Новичок здесь.

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

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

df1 = df.groupby(['Date', 'Facility'], as_index=False)['By_Name'].nunique()

Образец ввода (Sample.xlsx) заданного дня [фактические данные за каждый день месяца]:

ДатаСредствоВремя началаПо именинаставникПопечительЦиркулятор
2021-09-10Мыс Страх10:01DIКЛ
2021-09-10Мыс Страх10:31DIКЛ
2021-09-10Мыс Страх10:36DIКЛ
2021-09-10Мыс Страх11:58DIКЛ
2021-09-10Мыс Страх12:11DIКЛ
2021-09-10Мыс Страх12:56DIКЛ
2021-09-10Мыс Страх13:35DIКЛ
2021-09-10Мыс Страх17:30DIКЛ
2021-09-10Мыс Страх09:50КЛDI
2021-09-10Мыс Страх10:47КЛDI
2021-09-10Мыс Страх11:14КЛDI
2021-09-10Мыс Страх16:18КЛDI
2021-09-10Мыс Страх16:34КЛDI
2021-09-10Мыс Страх18:09КЛDI
2021-09-10Мыс Страх18:20КЛDI
2021-09-10Мыс Страх09:30LOAбелый
2021-09-10Мыс Страх09:48СРмладший
2021-09-10Мыс Страх11:03СРмладший
2021-09-10Мыс Страх12:10СРмладший
2021-09-10Мыс Страх13:10СРмладший
2021-09-10Мыс Страх13:34СРмладший
2021-09-10Мыс Страх13:55СРмладший
2021-09-10Мыс Страх16:19СРмладший
2021-09-10Мыс Страх16:19СРмладший
2021-09-10Мыс Страх16:43СРмладший
2021-09-10Мыс Страх16:43СРмладший
2021-09-10Мыс Страх17:09СРмладший
2021-09-10Мыс Страх11:52белый

Желаемый результат (по объектам)

ДатаСредствоЗаписиВремя началаПо именинаставникПопечительЦиркулятор
2021-09-10Мыс Страх609:30LOAбелый
2021-09-10Мыс Страх09:48СРмладший
2021-09-10Мыс Страх09:50КЛDI
2021-09-10Мыс Страх10:01DIКЛ

Любая помощь будет оценена по достоинству. ТИА

вам нужно использовать .count, а не nunique, не могли бы вы предоставить свои данные в pd.DataFrame, пожалуйста

DataSciRookie 17.05.2022 14:25
но не могу уловить логику, groupby и nunike выводят то, что вы хотите?
Ynjxsjmh 17.05.2022 14:27

@DataSciRookie .count дает мне общее количество всех значений, отличных от NaN. Я ищу только первое отчетливое вхождение. Что касается данных в pd.DataFrame, я пытаюсь вставить их сюда, но они не форматируются должным образом.

Norwegian Salmon 17.05.2022 14:48

@Ynjxsjmh groupby и nunique дают мне часть решения. Я получаю правильный счет для каждого из четырех столбцов, но затем мне нужно исключить счет, если он уже произошел. Пример: «ДИ» уже вошел в объект в «По имени», поэтому его счет не должен обновляться, когда он снова появится в «Циркуляторе».

Norwegian Salmon 17.05.2022 14:51

@GonçaloPeres Это почти готово, но то, с чем я борюсь, еще предстоит сделать. Если человек вошел на объект, это засчитывается как 1 вход (как вы можете видеть в желаемом выводе). Таким образом, общее количество записей должно быть 6 для плаща страха.

Norwegian Salmon 17.05.2022 15:31

@GonçaloPeres Да. И «Наставник», и «Наставник». Они пусты для этого объекта, но могут быть пустыми для других объектов/дат.

Norwegian Salmon 17.05.2022 15:48

@GonçaloPeres это будет то же самое, что и «По имени» или «Циркулятор». Допустим, это «AA» в «Наставнике» и XX в «Наставнике» в строках 1 и 5 соответственно.

Norwegian Salmon 17.05.2022 15:59
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
0
7
39
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

ОБНОВЛЕННЫЙ ОТВЕТ:

Основываясь на разъяснениях OP в комментариях, вот новая стратегия для получения того, что требуется:

df = df.set_index(['Date', 'Facility', 'Begin Time']).stack()
df.index=df.index.droplevel(3)
df = df.to_frame().rename(columns={0:'Name'}).reset_index()
df2 = df.groupby(['Date', 'Facility'])['Name'].nunique().to_frame().rename(columns={'Name': 'Entries'})
indexCols = ['Date', 'Facility', 'Entries']
df = df.join(df2, on=['Date', 'Facility']).reindex(columns=indexCols + list(set(df.columns) - set(indexCols)))
df = df.assign(TEMP_COL=0).groupby(indexCols + ['Name']).nth(0).drop(columns='TEMP_COL')

Объяснение:

  • Используя Date, Facility, Begin Time в качестве индекса, вызовите stack(), чтобы переставить четыре столбца, содержащие имена, в один столбец со старым именем столбца, указывающим «Вид имени» (By Name, Preceptor, Preceptee или Circulator), добавленным в качестве уровня мультииндекса строки.
  • Удалите уровень «Вид имени» (уровень 3) из мультииндекса строки.
  • Переименуйте столбец 0 в Name, вызовите reset_index(), чтобы переместить Date, Facility, Begin Time из мультииндекса строки и обратно в метки столбцов.
  • Используйте groupby() и nunique(), чтобы вычислить Entries: количество уникальных имен (во всех четырех исходных столбцах), связанных с каждым Date, Facility.
  • Используйте join(), чтобы добавить столбец Entries в исходный фрейм данных.
  • Используйте groupby() на Date, Facility, Name, затем используйте nth(0), чтобы получить первую строку каждой группы (включая ее Begin Time), также используя фиктивный столбец TEMP_COL, чтобы убедиться, что у нас не закончатся столбцы при выполнении groupby().

Пример 1 (используя исходный ввод из вопроса):

Выход:

                                  Begin Time
Date       Facility  Entries Name
2021-09-10 Cape Fear 6       DI        10:01
                             JR        09:48
                             KL        10:01
                             LOA       09:30
                             SR        09:48
                             WH        09:30

Пример 2 (добавляет второй Facility):

          Date      Facility Begin Time By Name  Preceptor  Preceptee Circulator
0   2021-09-11  Facility Two      10:01      AA       <NA>       <NA>         ZZ
1   2021-09-11  Facility Two      10:31      AA       <NA>       <NA>         ZZ
2   2021-09-11  Facility Two      10:36      AA       <NA>       <NA>         ZZ
3   2021-09-11  Facility Two      11:58      DI       <NA>       <NA>         KL
4   2021-09-11  Facility Two      12:11      DI       <NA>       <NA>         KL
5   2021-09-11  Facility Two      12:56      DI       <NA>       <NA>         KL
6   2021-09-11  Facility Two      13:35      DI       <NA>       <NA>         KL
7   2021-09-10     Cape Fear      10:01      DI       <NA>       <NA>         KL
8   2021-09-10     Cape Fear      10:31      DI       <NA>       <NA>         KL
9   2021-09-10     Cape Fear      10:36      DI       <NA>       <NA>         KL
10  2021-09-10     Cape Fear      11:58      DI       <NA>       <NA>         KL
11  2021-09-10     Cape Fear      12:11      DI       <NA>       <NA>         KL
12  2021-09-10     Cape Fear      12:56      DI       <NA>       <NA>         KL
13  2021-09-10     Cape Fear      13:35      DI       <NA>       <NA>         KL
14  2021-09-10     Cape Fear      17:30      DI       <NA>       <NA>         KL
15  2021-09-10     Cape Fear      09:50      KL       <NA>       <NA>         DI
16  2021-09-10     Cape Fear      10:47      KL       <NA>       <NA>         DI
17  2021-09-10     Cape Fear      11:14      KL       <NA>       <NA>         DI
18  2021-09-10     Cape Fear      16:18      KL       <NA>       <NA>         DI
19  2021-09-10     Cape Fear      16:34      KL       <NA>       <NA>         DI
20  2021-09-10     Cape Fear      18:09      KL       <NA>       <NA>         DI
21  2021-09-10     Cape Fear      18:20      KL       <NA>       <NA>         DI
22  2021-09-10     Cape Fear      09:30     LOA       <NA>       <NA>         WH
23  2021-09-10     Cape Fear      09:48      SR       <NA>       <NA>         JR
24  2021-09-10     Cape Fear      11:03      SR       <NA>       <NA>         JR
25  2021-09-10     Cape Fear      12:10      SR       <NA>       <NA>         JR
26  2021-09-10     Cape Fear      13:10      SR       <NA>       <NA>         JR
27  2021-09-10     Cape Fear      13:34      SR       <NA>       <NA>         JR
28  2021-09-10     Cape Fear      13:55      SR       <NA>       <NA>         JR
29  2021-09-10     Cape Fear      16:19      SR       <NA>       <NA>         JR
30  2021-09-10     Cape Fear      16:19      SR       <NA>       <NA>         JR
31  2021-09-10     Cape Fear      16:43      SR       <NA>       <NA>         JR
32  2021-09-10     Cape Fear      16:43      SR       <NA>       <NA>         JR
33  2021-09-10     Cape Fear      17:09      SR       <NA>       <NA>         JR
34  2021-09-10     Cape Fear      11:52      WH       <NA>       <NA>       <NA>

Выход:

2021-09-10 Cape Fear    6       DI        10:01
                                JR        09:48
                                KL        10:01
                                LOA       09:30
                                SR        09:48
                                WH        09:30
2021-09-11 Facility Two 4       AA        10:01
                                DI        11:58
                                KL        11:58
                                ZZ        10:01

ОРИГИНАЛЬНЫЙ ОТВЕТ:

Вот способ получить что-то близкое к тому, что ваш вопрос показывает как желаемый результат:

df1 = df.groupby(['Date', 'Facility'], as_index=False)['By Name'].nunique().rename(columns={'By Name': 'Entries'}).set_index(['Date', 'Facility'])
df2 = df[['Date', 'Facility', 'By Name']].join(df1, on=['Date', 'Facility'])

df = df.assign(Entries=df2['Entries']).reindex(columns=['Date', 'Facility', 'Entries'] + [col for col in df.columns if col not in ['Date', 'Facility']])
df = df.groupby(['Date', 'Facility', 'Entries', 'By Name']).nth(0)

Пример 1 (использует исходный ввод в вопросе):

          Date   Facility Begin Time By Name  Preceptor  Preceptee Circulator
0   2021-09-10  Cape Fear      10:01      DI       <NA>       <NA>         KL
1   2021-09-10  Cape Fear      10:31      DI       <NA>       <NA>         KL
2   2021-09-10  Cape Fear      10:36      DI       <NA>       <NA>         KL
3   2021-09-10  Cape Fear      11:58      DI       <NA>       <NA>         KL
4   2021-09-10  Cape Fear      12:11      DI       <NA>       <NA>         KL
5   2021-09-10  Cape Fear      12:56      DI       <NA>       <NA>         KL
6   2021-09-10  Cape Fear      13:35      DI       <NA>       <NA>         KL
7   2021-09-10  Cape Fear      17:30      DI       <NA>       <NA>         KL
8   2021-09-10  Cape Fear      09:50      KL       <NA>       <NA>         DI
9   2021-09-10  Cape Fear      10:47      KL       <NA>       <NA>         DI
10  2021-09-10  Cape Fear      11:14      KL       <NA>       <NA>         DI
11  2021-09-10  Cape Fear      16:18      KL       <NA>       <NA>         DI
12  2021-09-10  Cape Fear      16:34      KL       <NA>       <NA>         DI
13  2021-09-10  Cape Fear      18:09      KL       <NA>       <NA>         DI
14  2021-09-10  Cape Fear      18:20      KL       <NA>       <NA>         DI
15  2021-09-10  Cape Fear      09:30     LOA       <NA>       <NA>         WH
16  2021-09-10  Cape Fear      09:48      SR       <NA>       <NA>         JR
17  2021-09-10  Cape Fear      11:03      SR       <NA>       <NA>         JR
18  2021-09-10  Cape Fear      12:10      SR       <NA>       <NA>         JR
19  2021-09-10  Cape Fear      13:10      SR       <NA>       <NA>         JR
20  2021-09-10  Cape Fear      13:34      SR       <NA>       <NA>         JR
21  2021-09-10  Cape Fear      13:55      SR       <NA>       <NA>         JR
22  2021-09-10  Cape Fear      16:19      SR       <NA>       <NA>         JR
23  2021-09-10  Cape Fear      16:19      SR       <NA>       <NA>         JR
24  2021-09-10  Cape Fear      16:43      SR       <NA>       <NA>         JR
25  2021-09-10  Cape Fear      16:43      SR       <NA>       <NA>         JR
26  2021-09-10  Cape Fear      17:09      SR       <NA>       <NA>         JR
27  2021-09-10  Cape Fear      11:52      WH       <NA>       <NA>       <NA>

Выход:

                                     Begin Time  Preceptor  Preceptee Circulator
Date       Facility  Entries By Name
2021-09-10 Cape Fear 5       DI           10:01       <NA>       <NA>         KL
                             KL           09:50       <NA>       <NA>         DI
                             LOA          09:30       <NA>       <NA>         WH
                             SR           09:48       <NA>       <NA>         JR
                             WH           11:52       <NA>       <NA>       <NA>

Пример 2 (добавляет второй Facility): (см. ОБНОВЛЕННЫЙ ОТВЕТ выше для примера ввода.) Выход:

                                        Begin Time  Preceptor  Preceptee Circulator
Date       Facility     Entries By Name
2021-09-10 Cape Fear    5       DI           10:01       <NA>       <NA>         KL
                                KL           09:50       <NA>       <NA>         DI
                                LOA          09:30       <NA>       <NA>         WH
                                SR           09:48       <NA>       <NA>         JR
                                WH           11:52       <NA>       <NA>       <NA>
2021-09-11 Facility Two 2       AA           10:01       <NA>       <NA>         ZZ
                                DI           11:58       <NA>       <NA>         KL

Спасибо; Это очень близко. Но общее количество записей для «Cape Fear» должно быть 6, так как «JR» вошел в объект как «Circulator».

Norwegian Salmon 17.05.2022 15:55

Таким образом, «Записи» должны быть количеством уникальных имен во всех четырех столбцах («По имени», «Наставник», «Наставник» и «Распространитель»)?

constantstranger 17.05.2022 15:58

Да. Общее количество уникальных имен во всех четырех столбцах.

Norwegian Salmon 17.05.2022 16:01

ХОРОШО. В вашем «Желаемом результате» вам действительно нужен Begin Time в качестве столбца? Кроме того, будет ли достаточно иметь новый столбец с именем Unique Names вместо четырех столбцов (по имени, наставнику, наставнику и распространителю) с 6 строками, по одной для каждого уникального имени?

constantstranger 17.05.2022 16:23

Мне понадобится «Время начала» для дальнейшего анализа этих данных, поскольку есть несколько условий, которые мне нужно поставить после сортировки этих данных. Да, было бы достаточно иметь новую колонку.

Norwegian Salmon 17.05.2022 16:32

Хорошо понял. Пожалуйста, смотрите мой обновленный ответ, чтобы узнать, что я думаю, будет делать то, что вы хотите.

constantstranger 17.05.2022 19:08

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