Уже больше месяца экспериментирую, исследую, как разные схемы (паттерны) осознанного дыхания влияют на вариабельность сердечного ритма (Heart Rate Variability, HRV на чуждом языке). В скромной, но не совсем уж крошечной Excel-таблице со столбцами “Паттерн”, “HRV”, “Пульс” набралось 258 записей и мне понадобилось выбрать победителя -- дыхательный паттерн, дающий на выходе максимальное значение HRV. Не вручную же сортировать эти записи!

Да, я знаю: есть Pivot Table & Power Query. Но Pivot Table мне не по душе необходимостью после каждого изменения таблицы-источника делать REFRESH, во-первых, избыточной сложностью создания, во-вторых. И просто так не нравятся Pivot Table, что главное. Что же касается Power Query, то сочетание слов вызывает у меня трепет и учащенное сердцебиение: не понимаю, что это за зверь такой и насколько он страшный или полезный. 

Поэтому для подсчета результатов -- и выбора победителя -- применил относительно недавно появившуюся в Excel функцию GROUPBY в связке с XLOOKUP. И, раз уж пришлось группировать данные, решил сравнить нативные функции Excel с GROUPBY от Pandas (мы ведь помним, что сейчас Python можно запустить внутри Excel).  

Python в Excel? Почему бы и нет.
Python в Excel? Почему бы и нет.

Написал простой код: 

df = xl("Table5[#All]", headers=True) 

df = df.dropna(subset=['HRV']) 

#select patterns which are recorded >= 6 times 
patterns = df.breathing_pattern.to_list() 
patterns = list(set([i for i in patterns if patterns.count(i) >= 6])) 
df = df[df.breathing_pattern.isin(patterns)] 

patterns_efficacy = df.groupby("breathing_pattern").mean( 
['HRV','HR'] 
).astype(int).reset_index() 

patterns_efficacy = patterns_efficacy.sort_values(by=['HRV'], ascending=False) 

patterns_efficacy 

Поместил код через =PY( в ячейку А1 Excel

И он прекрасно справился с задачей и выдал таблицу с результатами: 

 

breathing_pattern 

HRV 

HR 

physiological sighs moderate 

59 

65 

physiological sighs light 

57 

62 

4.4-6.6 

56 

59 

following pulse 

55 

61 

4.2-0-6.4-0 

53 

62 

6-6 

53 

61 

calming breathing: inhale through nose, slow exhale through mouth 

53 

61 

5-5 

52 

63 

count: 4 inhale nose, 6 exhale mouth 

52 

63 

Комбинация функций GROUPBY и XLOOKUP тоже отработала без изъянов:

Для группировки по HRV в ячейку E1 
  =GROUPBY(Table5[[#All],[breathing_pattern]],Table5[[#All],[HRV]], AVERAGE,3,0,-2) 

Для группировки по пульсу в ячейку E13 
  =GROUPBY(Table5[[#All],[breathing_pattern]],Table5[[#All],[HR]], AVERAGE,3,0,-2) 

И для объединения в одну общую таблицу в ячейку G2 
  =XLOOKUP(E2:E10,E14:E22,F14:F22,"not found") 

breathing_pattern 

HRV 

HR 

physiological sighs moderate 

59 

65 

physiological sighs light 

57 

63 

4.4-6.6 

56 

60 

following pulse 

55 

61 

4.2-0-6.4-0 

54 

63 

6-6 

54 

61 

calming breathing: inhale through nose, slow exhale through mouth 

53 

62 

5-5 

53 

63 

count: 4 inhale nose, 6 exhale mouth 

52 

63 

* Для внимательных: разница в данных между двумя таблицами -- плод Python-овского округления до целых чисел.  

* В “нативном” подходе нет отсечки паттернов с количеством замеров менее шести.

Выводы и наблюдения по теме: 

  1. В Python итоговая таблица сама автоматически изменяет размеры при добавлении новых паттернов. GROUPBY by Excel ведет себя так же, а вот связка GROUPBY&XLOOKUP уже потребует редактирования формул: нужно изменять адреса диапазонов ячеек, к которым обращается XLOOKUP. 

  1. Вопреки большему размеру Python-код мне кажется проще и для написания, и для чтения-понимания. Хотя писать код в ячейке Excel -- весьма извращенное удовольствие. 

  1. Исполнение кода Python требует интернет-соединения. 

 

Выводы и наблюдения не совсем по теме:  

  1. Для меня лично схема дыхания “physiological sighs light” (легкие физиогические вздохи) -- оптимальный выбор.  

  1. Более шести месяцев я придумывал, зачем мне может понадобиться живущий в Excel Python и наконец нашел. 

Буду благодарен за советы и критику. Постараюсь ответить на вопросы.

Комментарии (23)


  1. vtal007
    03.06.2024 14:31
    +1

    Кажется это оверхед (или как это правильно называется)

    может проще было "промежуточные итоги", а потом сортировка

    Просто данных я не вижу и непонятно, что считалось

    Паверквери - можно ознакомится на ютубе есть лекции от "товарищ эксель" , но кажется PQ не для Вашей задачи

    а если уходить в питон. да сразу развернуть юпитер локально, закинуть туда файл эксель/csv и там уже отрабатывать

    С другой стороны питон хорош для автоматизации


    1. Gonchar_POTT Автор
      03.06.2024 14:31

      Таблица вот такого вида. Подход через запуск отдельного исполняемого Python-файла или Jupyter Notebook мне кажется избыточным.


      1. vtal007
        03.06.2024 14:31
        +5

        да тут кажется просто сводная таблица и все. Не? (вот этот же код группирует и выводит средние по двум переменным "groupby("breathing_pattern").mean( ['HRV','HR'] "

        258 строк это вообще ниачем, это даже не 258 тысяч (и их бы эксель прожевал спокойно, вот 2 миллиона уже без паверквери не получилось бы)

        Так-то мне и питон тут излишним. питон в экселе это наверно скорее замена VBA, для современного поколения дата-аналитиков


      1. Aizz
        03.06.2024 14:31
        +1

        Ничего не хочу сказать, но вам достаточно было сделать дополнительную колонку со "Средним значением" и куда-нибудь отдельно вынести поиск максимального значения с INDEX+MATCH
        Достаточно будет вносить новые значения и смотреть на результат.
        https://i.imgur.com/n5Qj2PU.png


        1. Gonchar_POTT Автор
          03.06.2024 14:31

          За подсказку спасибо! Способов действительно много.


  1. itGuevara
    03.06.2024 14:31

    1. Исполнение кода Python требует интернет-соединения. 

    Off-line никак?


    1. economist75
      03.06.2024 14:31
      +1

      Уже 6 лет как библиотеки PyXLL и XLWIngs дают Python/Pandas внутри Excel 2007-10-13-16-19.


      1. Gonchar_POTT Автор
        03.06.2024 14:31

        Не знал, спасибо.


    1. Gonchar_POTT Автор
      03.06.2024 14:31

      Нет, оффлайн не работает: код исполняется на сервере Microsoft.


  1. Kahelman
    03.06.2024 14:31

    Можно накатать код на чистом VBA живет в excel,

    Можно на powershell- есть модуль для работы с excel.

    Ещё вариант выкинуть данные в csv- импортировать в SQLite. Где выполнить запрос и выдать результаты.

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


    1. Gonchar_POTT Автор
      03.06.2024 14:31

      В данной ситуации (не умею ни в VBA, ни в SQLite, мизерный объем данных, постоянное Интернет-подключение, умею в Pandas) мне показалось рациональным задействовать именно Python в Excel. И, не скрою, очень хотелось найти ему применение.


      1. Kahelman
        03.06.2024 14:31
        +1

        ЧатГпт в помощь :)

        Решение прикольное не нравится что все через сайт МС. Сегодня соединение есть, завтра нет.

        Кстати скормите задачу Чату ГПТ и посмотрите что он вам находит. Конечно придётся доработать напильником.


        1. Gonchar_POTT Автор
          03.06.2024 14:31

          ChatGPT можно скормить сырые данные и он их обработает, это да. И несложный код написать сможет.


  1. LexX80
    03.06.2024 14:31

    Попробуйте использовать jupyter, не в составе google colab, а в установке на рабочий ПК(если зайдет, можно в северном исполнении сделать).

    Я в свое время использовал jupyter для разбора финансовых показателей для отчёта, данных было очень много иЭксель плакал и звал маму, pandas тратил секунды на это.


    1. Gonchar_POTT Автор
      03.06.2024 14:31

      Я постоянно использую локальный Jupyter Notebook на РС, отличный инструмент для определеных (не всех) задач. Здесь же идея в том, что все действия - и записи новых данных, и их обработка - происходят внутри одного файла. Открыл Excel, внёс новые строки в таблицу и сразу видишь результаты.


  1. Raevus
    03.06.2024 14:31
    +1

    Так и раньше можно было использовать питон через Excel, причём все работает оффлайн. Для этого нужно написать макрос на VBA и вызвать питон скрипт, передав ему через параметры путь к данному Excel, название листа и все прочее.


  1. smnmegatron
    03.06.2024 14:31
    +2

    "необходимостью после каждого изменения таблицы-источника делать REFRESH" в pandas тоже нужно код перезапустить, если данные в источнике обновились. Частично проблема обновления решается ДВССЫЛ, именоваными диапазонами. Но проблема кнопки-обновить остается.


    1. Gonchar_POTT Автор
      03.06.2024 14:31

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


      1. smnmegatron
        03.06.2024 14:31

        Возможно, я не понимаю как работает эта строка: df = xl("Table5[#All]", headers=True)


        1. Gonchar_POTT Автор
          03.06.2024 14:31

          df = xl("Table5[#All]", headers=True)

          Из таблицы Excel "Table5" создается Python-объект, DataFrame. [#All] значит, что таблица используется полностью -- и данные, и header.


          1. smnmegatron
            03.06.2024 14:31

            Функция xl не является стандартной функцией Pandas или Python, поэтому предполагается, что это пользовательская функция или функция из сторонней библиотеки, которая возвращает DataFrame?


            1. Gonchar_POTT Автор
              03.06.2024 14:31

              Функция xl — стандартная функция Excel, которая, принимая одним из аргументов объект Excel, конвертирует его в объект Python, не обязательно датафрейм. Что-то вроде моста между Excel на локальном компьютере и Python на сервере Microsoft. Хотя аналогия с мостом — не очень удачная, ничего другого мне в голову не приходит.


    1. Gonchar_POTT Автор
      03.06.2024 14:31

      На всякий случай: этот Python-код "живет" в ячейке A1, а не в отдельном файле. Это я забыл (упустил) акцентировать. И не требует привычного запуска.