#python #pandas #time-series
#python #pandas #временные ряды
Вопрос:
Я был в тупике по этому поводу, и — что нехарактерно — Интернет мало помог. Я работаю в Pandas, но я чувствую, что это должно быть общей проблемой для людей, стремящихся эффективно хранить данные временных рядов.
У меня много стандартных данных ежедневных временных рядов, где значения меняются нечасто, например:
Date Value
01/02/2014 .1
01/03/2014 .1
01/04/2014 .5
01/05/2014 .5
01/06/2014 .5
01/07/2014 .1
Я бы преобразовал данные только для отслеживания дней, когда изменяется значение, поэтому приведенный выше пример теперь должен выглядеть так:
Date Value
01/02/2014 .1
01/04/2014 .5
01/07/2014 .1
К сожалению, использование чего-то подобного drop_duplicates()
приведет к удалению требуемых значений в случае, когда значение возвращается к предыдущему значению (например .1 в моем примере выше).
Ответ №1:
Используйте комбинацию shift
и all
:
In [98]:
import io
temp = """Date,Value
01/02/2014,.1
01/03/2014,.1
01/04/2014,.5
01/05/2014,.5
01/06/2014,.5
01/07/2014,.1"""
df = pd.read_csv(io.StringIO(temp))
df
Out[98]:
Date Value
0 01/02/2014 0.1
1 01/03/2014 0.1
2 01/04/2014 0.5
3 01/05/2014 0.5
4 01/06/2014 0.5
5 01/07/2014 0.1
In [99]:
df.loc[(df.shift() != df).all(axis=1)]
Out[99]:
Date Value
0 01/02/2014 0.1
2 01/04/2014 0.5
5 01/07/2014 0.1
Здесь мы сравниваем сдвинутый (на 1 строку) фрейм данных с исходным фреймом данных, затем мы хотим сравнить каждый столбец и использовать all
и передавать axis=1
для достижения этой цели.
Дальнейшая разбивка, если мы посмотрим, что df.shift() != df
возвращает:
In [100]:
df.shift() != df
Out[100]:
Date Value
0 True True
1 True False
2 True True
3 True False
4 True False
5 True True
Мы получаем фрейм данных с логическими значениями, но мы не можем использовать это как маску как есть, мы хотим проверить, что все строки таковы True
, что мы используем all
:
In [101]:
(df.shift() != df).all()
Out[101]:
Date True
Value False
dtype: bool
Однако по умолчанию проверяется, что столбцы все True
, мы хотим проверить значения строк, поэтому мы передаем axis=1
:
In [102]:
(df.shift() != df).all(axis=1)
Out[102]:
0 True
1 False
2 True
3 False
4 False
5 True
dtype: bool
Теперь мы можем использовать это как нашу логическую маску для достижения того, чего мы хотели:
In [103]:
df.loc[(df.shift() != df).all(axis=1)]
Out[103]:
Date Value
0 01/02/2014 0.1
2 01/04/2014 0.5
5 01/07/2014 0.1
Комментарии:
1. хм … хотя мы добавили это в кулинарную книгу (и, возможно, где-то в основных документах). хотите это сделать? полный пример этого
2. @Джефф рад, это просто ссылка на этот ответ?
3. Я думаю, что небольшой полный пример был бы хорош (я считаю, что встроенный код лучше для небольшого примера)
4. @Jeff нужно ли мне загружать исходный код и компилировать его: pandas.pydata.org / … не уверен, что у меня возникнут проблемы, поскольку я использую WinPython, который поставляется с python
5. @Jeff спасибо за ссылку, я попробую и посмотрю, как у меня дела, я хотел бы внести больший вклад, а не просто мои основные ответы на SO