Как получить среднее значение последовательности, используя итератор в Pandas?

В настоящее время я использую pandas для управления файлом CSV, содержащим данные о местонахождении судов на карте. У меня есть фрейм данных Pandas, который выглядит так (упрощенно):

Индекс Группа C_p 1 1 27 2 1 85 3 1 83 4 1 78 5 1 66 6 1 47 7 3 82 8 3 80 9 3 66

C_p — коэффициент достоверности, позволяющий судить о том, припарковано ли судно.

Способ оценки припаркованного судна следующий:

Если среднее значение C_p последовательности данных выше 80, эта последовательность данных является припаркованным судном, а минимальный номер последовательности выше 3.

Таким образом, в этом примере индексы от 2 до 4 представляют собой последовательность припаркованных судов, поскольку среднее значение C_p составляет 82,67, что превышает 80. Несмотря на то, что индексы от 7 до 8, среднее значение C_p превышает 80, последовательность состоит всего из двух элементов. так что это не припаркованное судно.

Итак, я хочу получить это:

Индекс Группа C_p is_parked 1 1 27 0 2 1 85 1 3 1 83 1 4 1 78 1 5 1 66 0 6 1 47 0 7 3 82 0 8 3 80 0 9 3 66 0

Я пытаюсь изменить этот метод на вопрос Leetcode, например:

for i in range(n - 2): # n is the element number of a group
    avg = (C_p[i] + C_p[i+1] + C_p[i+2]) / 3
    if avg >= 80:
        is_parked[i] = is_parked[i+1] = is_parked[i+2] = 1 # default value of is_parked is 0

Но я понятия не имею, как реализовать это с помощью Pandas или Python.

Итак, мой вопрос:

  1. Есть ли способ реализовать это в Pandas?

  2. Если нет, следует ли мне обратиться к Numpy или к чему-то еще, чтобы получить результаты?


Обновлено: 1 Комментарий Ника позволяет мне перепроверить мой пример и мой метод.

Если C_p[5] = 78, это все еще припаркованное судно и оно рассчитывается для каждой группы.

Я не учел этого, поэтому моя первая попытка была неудачной. Вот моя новая попытка

for i in range(n):
    thisSUM = C_p[i]
    for j in range(i+1, n):
        thisSUM += C_p[j]
        avg = thisSUM / (j - i + 1)
        if avg >= 80 and j - i + 1 >= 3:
            for k in range(i, j+1):
                is_parked_check[k] = 1

Временная сложность равна O(n^3), что нехорошо.

А что, если C_p[5] = 78? Это все еще припаркованное судно (поскольку последовательность из 2-5 имеет среднее значение >= 80) или не припарковано (поскольку последовательность из 3-5 имеет среднее значение <= 80)?

Nick 12.03.2024 08:09

Кроме того, это должно рассчитываться индивидуально или на основе всех данных?

Nick 12.03.2024 08:09

Моя попытка ошибочна. Если C_p[5] = 78, это все еще припаркованное судно и оно рассчитывается для каждой группы. Спасибо, что напомнили.

AndrewChao 12.03.2024 08:14
Почему в 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
3
64
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы можете использовать двойное перекатывание в groupby.transform. Первый — вычислить скользящее среднее, затем мы проверяем, превышает ли значение пороговое значение. Затем мы переворачиваем серию и вычисляем скользящий максимум, чтобы распространить значение True/1 на предыдущие строки N-1:

N = 3
threshold = 80

df['is_parked'] = (df.groupby('Group')['C_p']
                     .transform(
                        lambda s: s.rolling(N).mean().gt(threshold)[::-1]
                                   .rolling(N, min_periods=1).max()
                                   .astype(int)
                     )
                   )

Выход:

   Index  Group  C_p  is_parked
0      1      1   27          0
1      2      1   85          1
2      3      1   83          1
3      4      1   78          1
4      5      1   66          0
5      6      1   47          0
6      7      3   82          0
7      8      3   80          0
8      9      3   66          0

Промежуточные продукты:

   Index  Group  C_p       formula        avg    >80  rev_roll
0      1      1   27           NaN        NaN  False         0
1      2      1   85           NaN        NaN  False         1
2      3      1   83  (83+85+27)/3  65.000000  False         1
3      4      1   78  (78+83+85)/3  82.000000   True         1
4      5      1   66  (66+78+83)/3  75.666667  False         0
5      6      1   47  (47+66+78)/3  63.666667  False         0
6      7      3   82           NaN        NaN  False         0
7      8      3   80           NaN        NaN  False         0
8      9      3   66  (66+80+82)/3  76.000000  False         0

Спасибо, что просветили меня, но мой первый метод был неправильным. Я добавляю свой новый метод в недавнее редактирование.

AndrewChao 12.03.2024 09:37

@AndrewChao Я считаю, что мой код уже делает то, что вы хотите. Я добавил некоторые детали, пожалуйста, проверьте еще раз и уточните, если необходимо.

mozway 12.03.2024 11:23

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