#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 лет спустя