【问题标题】:numpy possible bug? doing timedeltas on columnsnumpy 可能的错误?在列上做 timedeltas
【发布时间】:2014-03-28 14:07:00
【问题描述】:

我的问题很简单。我有来自 twitter 的时间戳数据。每行是一个用户,每一列给出用户最后一次推特。

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    

我想做的是获得时差。对于每一列,我想将日期和时间替换为自上次发布以来的时间。例如,如果我的第一篇文章发生在晚上 8 点,而我的第二篇文章发生在 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')

这似乎是对的,除了某些单元格之外,它返回的结果与输入无关,例如 400 万秒,它应该是 100 万秒。有时它甚至会返回否定结果,正如您在上面的输出示例中所见。

有人能解释发生了什么吗?建议一个更好的方法来做到这一点?

我使用的是 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 天。

非常感谢您的帮助!

【问题讨论】:

  • 您的代码示例不完整,因为column_namespd (=pandas.io.parsers?) 都没有定义。
  • 请发布 pandas/numpy 的版本。您至少需要使用 numpy 1.7.1(numpy 1.6 完全有问题)
  • 感谢您的指出,我马上更改。
  • 好的,我更改了代码并添加了我正在使用的库的版本:numpy 为 1.8.0,pandas 为 0.13.0。再次感谢。

标签: python datetime numpy pandas timedelta


【解决方案1】:

Timedelta 文档是here

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'))

【讨论】:

  • 杰夫,非常感谢您的回答,但这样做会给我与以前相同的不一致结果(例如一些负值)。我的数据有可能在某种程度上是错误的吗?为了更清楚,我将它们添加到我的问题中。
  • 您可能需要dayfirst=True,因为您的日期似乎不是通用格式。打印出来的日期看起来正确吗?
  • 在我看来,日子已经排在第一位了,在我在问题中发布的示例中,或者...?
  • 好的,添加 dayfirst=True 似乎可以解决问题。非常感谢!你这周第二次救了我的命!
猜你喜欢
  • 2016-05-27
  • 1970-01-01
  • 2014-11-13
  • 1970-01-01
  • 1970-01-01
  • 2018-09-06
  • 1970-01-01
  • 2016-06-22
  • 2015-02-04
相关资源
最近更新 更多