#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
.