использование переходящих функций в pandas с серией, где индекс времени очень разрежен

#python #pandas

#python #pandas

Вопрос:

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

Я хотел бы вычислить переходящий минимум / максимум, но я не могу заставить его работать.

Индекс построен таким образом:

 df['timestamp'] = pd.to_datetime(df['timestamp'], unit='ms')
  

Сначала я попробовал это:

 df['rolling_low'] = df['price'].rolling('1m').min()
  

но затем я получаю эту ошибку:

window должно быть целым числом

просматривая различные сообщения, я попробовал это:

 df['rolling_low'] = df.rolling('1m', on='timestamp')['price'].min()
  

по какой-то причине синтаксис отличается от первой попытки, но в любом случае, это дает мне:

временная метка должна быть монотонной

Еще один поиск по SO, и я добавил это:

 df = df.sort_index()
  

но это все та же проблема.

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

Что именно означает ошибка? и, кроме того, как мне это исправить 🙂

Ответ №1:

Когда вы делаете следующее: df['rolling_low'] = df['price'].rolling('1m').min() вы должны убедиться, что ваша временная метка является индексом фрейма данных. Это делается в: df = df.set_index("timestamp") в примере кода ниже, в противном случае вы получите ValueError: window must be an integer ошибку. Я согласен, что ошибка довольно туманна в этом контексте. Вот рабочий пример 🙂

 import pandas as pd


df = pd.DataFrame(
    {
        "timestamp": [
            "2020-04-20 12:00:00.123",
            "2020-04-20 12:00:00.126",
            "2020-04-20 12:00:00.128",
            "2020-04-20 12:00:05.126",
            "2020-04-20 12:00:05.140",
            "2020-04-20 12:00:05.156",
            "2020-04-20 12:00:12.126",
            "2020-04-20 12:00:12.129",
        ],
        "price": range(8),
    }
)
df["timestamp"] = pd.to_datetime(df["timestamp"])
df = df.set_index("timestamp")
df["rolling_low"] = df["price"].rolling("1s").min()
  

Вывод:

                          price  rolling_low
timestamp
2020-04-20 12:00:00.123      0          0.0
2020-04-20 12:00:00.126      1          0.0
2020-04-20 12:00:00.128      2          0.0
2020-04-20 12:00:05.126      3          3.0
2020-04-20 12:00:05.140      4          3.0
2020-04-20 12:00:05.156      5          3.0
2020-04-20 12:00:12.126      6          6.0
2020-04-20 12:00:12.129      7          6.0
  

Если вы хотите выполнить агрегирование за 1 минуту, используйте «60 секунд» в качестве аргумента для rolling .