возможная ошибка? делать timedeltas на столбцах

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

time_0                  time_1            time_2             time_3     
21/03/2014 16:17    21/03/2014 15:40    21/03/2014 14:55    21/03/2014 12:50         
21/03/2014 16:29    21/03/2014 16:26    21/03/2014 16:23    21/03/2014 16:21    
04/07/2012 13:43    04/07/2012 13:37    04/07/2012 13:34    04/07/2012 13:29        
19/03/2014 01:41    18/03/2014 01:19    17/03/2014 00:50    05/03/2014 22:30    

То, что я хотел бы сделать, это получить разницу во времени. Для каждого столбца я хотел бы заменить дату и время временем, прошедшим с момента последнего сообщения. Например, если мой первый пост был в 20:00, а второй — в 8:45, я хочу получить «45 минут» в первом столбце. В идеале мой вывод такой (разница считается в секундах)

time_0  time_1     time_2       time_3
2220    2700       7500         43860
180     180        120            0
360     180        300           300
87720   88140   -4138800       5794500
60        0         0             0
74340   1800        0            540

Я делаю это так:

df = pandas.read_csv("testtimedelta.csv",header=0,parse_dates=column_names)
df=df.dropna()#get rid of not complete rows

column_names=[]
for i in range(100):
    column_names.append('time_'+str(i))

deltadatas=df[column_names]
for i in range(len(column_names)-1): 
    deltadatas[column_names[i]]=deltadatas[column_names[i]]-deltadatas[column_names[i+1]]/ np.timedelta64(1,'s')

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

Кто-нибудь может объяснить, что произошло? Предложите лучший способ сделать это?

Я использую numpy версии 1.8.0 и pandas версии 0.13.0.

РЕДАКТИРОВАТЬ: пример того, что не так.

state   followers   friends tweets_number   time_0                  source_0        time_1                   source_1          time_2                source_2        time_3
Bot     3890        2222        1211        19/03/2014 01:41        twitterfeed     18/03/2014 01:19        twitterfeed     17/03/2014 00:50        twitterfeed     05/03/2014 22:30

В этом примере time2-time3 даст мне -47 дней, что невозможно, и если я сделаю то, что @Jeff предложил ниже, снова 47 дней.

Большое спасибо за любую помощь!!


person Barnabe    schedule 28.03.2014    source источник
comment
Ваш пример кода неполный, поскольку ни column_names, ни pd (= pandas.io.parsers?) не определены.   -  person aepsil0n    schedule 28.03.2014
comment
Пожалуйста, опубликуйте версию pandas/numpy. вам нужно использовать как минимум numpy 1.7.1 (numpy 1.6 полностью глючит)   -  person Jeff    schedule 28.03.2014
comment
спасибо за указание, я меняю это сразу.   -  person Barnabe    schedule 28.03.2014
comment
хорошо, я изменил свой код и добавил версии библиотек, которые я использую: 1.8.0 для numpy и 0.13.0 для pandas. Спасибо еще раз.   -  person Barnabe    schedule 28.03.2014


Ответы (1)


Документы Timedelta находятся здесь

In [29]: df1 = DataFrame(dict([ ("t{0}".format(i),date_range('20130101 01:0{0}'.format(i*3),periods=5,freq='T')) for i in range(2) ]))

In [30]: df2 = DataFrame(dict([ ("t{0}".format(i+3),date_range('20130101 01:0{0}'.format(i*5),periods=5,freq='T')) for i in range(2) ]))

In [31]: df = df1.join(df2)

In [32]: df
Out[32]: 
                   t0                  t1                  t3                  t4
0 2013-01-01 01:00:00 2013-01-01 01:03:00 2013-01-01 01:00:00 2013-01-01 01:05:00
1 2013-01-01 01:01:00 2013-01-01 01:04:00 2013-01-01 01:01:00 2013-01-01 01:06:00
2 2013-01-01 01:02:00 2013-01-01 01:05:00 2013-01-01 01:02:00 2013-01-01 01:07:00
3 2013-01-01 01:03:00 2013-01-01 01:06:00 2013-01-01 01:03:00 2013-01-01 01:08:00
4 2013-01-01 01:04:00 2013-01-01 01:07:00 2013-01-01 01:04:00 2013-01-01 01:09:00

[5 rows x 4 columns]

In [33]: (df.T-df.T.shift()).T.astype('timedelta64[s]')
Out[33]: 
   t0   t1   t3   t4
0 NaN  180 -180  300
1 NaN  180 -180  300
2 NaN  180 -180  300
3 NaN  180 -180  300
4 NaN  180 -180  300

[5 rows x 4 columns]

IIRC astype требует pandas 0.13.1 (но вы всегда можете df.apply(lambda x: x/np.timedelta64(1,'s'))

person Jeff    schedule 28.03.2014
comment
Джефф, большое спасибо за ваш ответ, но это дает мне те же противоречивые результаты, что и раньше (например, некоторые отрицательные значения). Возможно ли, что мои данные в чем-то неверны? Я добавляю их к моему вопросу для большей ясности. - person Barnabe; 28.03.2014
comment
вам может понадобиться dayfirst=True, так как ваши даты не являются общепринятым форматом. Даты выглядят правильно, когда вы их распечатываете? - person Jeff; 28.03.2014
comment
мне кажется, что дни уже на первом месте, в примере, который я разместил в своем вопросе, или...? - person Barnabe; 28.03.2014
comment
Хорошо, добавление dayfirst=True, похоже, решает проблему. Большое спасибо! Ты спас мне жизнь второй раз за неделю! - person Barnabe; 28.03.2014