pandas TimeSeries diff() возвращается к серии

#python #pandas

#python #pandas

Вопрос:

Я работаю с некоторыми данными временных рядов в этом формате:

1984-12-12 14:08:00
1984-12-12 14:25:00
1984-12-12 14:47:00
1984-12-12 16:37:00
1984-12-12 16:37:00
1984-12-12 16:37:00
1984-12-12 17:52:00
1984-12-12 17:52:00
1984-12-12 19:29:00

За последние несколько days! то, что казалось несколькими простыми операциями (приятный день), превратилось в халтуру и уныние.

Кстати, вот требования:

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

Во-первых, когда я подхожу к pandas и всей group-apply-combine парадигме, что мне нравится делать, это

  • создайте некоторую группу над фреймом данных
  • напишите функцию, которая принимает объект group и возвращает объект group
  • используйте lamda apply для передачи групп в функцию

Я считаю, что это стандартно, и причина, по которой мне нравится его использовать, заключается в неявном объединении групп, нескольких столбцов и вставке нового столбца. (это также устраняет зацикливание на группах, упрощает векторизацию) … но я думаю, что у него проблемы с пустыми группами…

В любом случае, чтобы получить различия временных рядов, я обнаружил, что использование shift() для получения различий во времени выдало StopIteration ошибку, использование diff(1) не выдало ошибок.

Однако новый столбец delta (разница во времени между строками с событиями) превращается в серию.

 time                   ev             delta

1984-12-12 14:08:00        1           NaT  
1984-12-12 14:25:00        1      00:17:00  
1984-12-12 14:47:00        1      00:22:00  
1984-12-12 16:37:00        0      01:50:00  
1984-12-12 16:37:00        1      01:50:00  
1984-12-12 16:37:00        0      01:50:00  
1984-12-12 17:52:00        0      01:15:00  
1984-12-12 17:52:00        1      01:15:00  
1984-12-12 19:29:00        1      01:37:00 
  

Попытка преобразовать Series в TimeSeries оказалась бесплодной. Выдается ошибка из-за проблемы с форматом (найдено очень длинное число L не в формате часа, минуты, секунды), это, по-видимому, прерывает всю попытку, и try catch не может пройти мимо этого.

     try:
        pd.to_datetime(d['delta'], format='%H:%M:%S')
    except:
        pass
  

Еще одна ошибка, которая продолжает появляться, — это StopIteration ошибка при получении суммы времен.

 gg['cumt'] = pd.rolling_apply( gg['time'], 2, np.sum )
gg['cumt'] = pd.rolling_sum(gg['time'],2).shift(1)
gg['cumt'] = gg.apply(lambda x: pd.expanding_sum(x['time'], min_periods=2) )
  

Я считаю, что это простое, cumsum не выдало ошибку, gg['cumt'] = gg['tavg'].cumsum() но проблема с форматированием времени приводит к преобразованию строки в некоторый int, и они суммируются как крошечные числа.

Приветствуется любая помощь, общая или конкретная:

Мне нравится простая идея написать функцию и вернуть группу. Не слишком изучал transform функцию (не думаю, что смогу заставить ее работать); устраняет ли возврат измененных групп в функциях необходимость в преобразованиях / трансляции. Это то, что вызывает мою StopIteration ошибку? У меня такое ощущение, что он не может справиться с тем, что некоторые группы пусты?

Комментарии:

1. Показать ожидаемые результаты.

2. Как по мне, ваш столбец time является Datetime Series не Time Series , а delta есть Time Series . Например, вы можете добавить df['time'] df['delta'] и вы получите новые дату и время.

3. какая версия pandas / numpy? пожалуйста, покажите ваш код полностью и ожидаемый результат

4. вы не можете преобразовать timedelta в datetime, это не имеет смысла. (следовательно, ваше to_datetime ничего не делает) и вызывает корректно

Ответ №1:

Pandas 0.12.0, Numpy 1.7.1, Python 2.7.5, Linux Mint

 import pandas as pd
import StringIO

data = '''time
1984-12-12 14:08:00
1984-12-12 14:25:00
1984-12-12 14:47:00
1984-12-12 16:37:00
1984-12-12 16:37:00
1984-12-12 16:37:00
1984-12-12 17:52:00
1984-12-12 17:52:00
1984-12-12 19:29:00'''

df = pd.read_csv(StringIO.StringIO(data))

df['time'] = pd.DatetimeIndex(df['time'])

df['delta'] = df['time'].diff()

#df['delta'] = pd.TimeSeries(df['delta']) # sorry, not needed

#df['delta'][0] = 0 # to remove NaT 

# better method to remove NaT - thanks to Jeff
df['delta'] = df['delta'].fillna(0) 

df['cumsum'] = df['delta'].cumsum()

print df
  

Результат

                    time      delta     cumsum
0   1984-12-12 14:08:00   00:00:00   00:00:00
1   1984-12-12 14:25:00   00:17:00   00:17:00
2   1984-12-12 14:47:00   00:22:00   00:39:00
3   1984-12-12 16:37:00   01:50:00   02:29:00
4   1984-12-12 16:37:00   00:00:00   02:29:00
5   1984-12-12 16:37:00   00:00:00   02:29:00
6   1984-12-12 17:52:00   01:15:00   03:44:00
7   1984-12-12 17:52:00   00:00:00   03:44:00
8   1984-12-12 19:29:00   01:37:00   05:21:00
  

Комментарии:

1. следует df['delta'] = df['delta'].fillna(0) скорее выполнять цепную индексацию df['delta'][0] = 0 (которая работает, потому что у вас нет смешанных dtypes, отличных от datetime / timedelta)

2. @Jeff Спасибо, я новичок в pandas, и я изучаю это, отвечая на вопрос 🙂 Я искал что-то вроде fillna(0) прямо сейчас в Google, но я не знал, какое имя у него может быть.

3. np. см pandas.pydata.org/pandas-docs/stable /… для ссылки на цепную индексацию.

4. Спасибо! да, это была ошибка fillna (0) .. я должен был подумать об этом, поскольку у меня были похожие ошибки ‘u column’ в группах раньше, которые были устранены с помощью pd.isnull … также не знал о fillna… еще раз спасибо!

5. Приветствую Джеффа — ваш совет fillna только что помог… более 4 лет спустя