2014-04-11 112 views
4

我使用熊貓導入包含一列時間戳(逐行增加)的csv文件(大約一百萬行,5列)格式爲Hour:Min:Sec.Millsecs,例如將時間字符串(小時:分鐘:秒)快速轉換爲浮點數

11:52:55.162

和一些其他帶浮點的列。我需要將時間戳列轉換爲浮點數(以秒爲單位)。到目前爲止,我使用

pandas.read_csv 

得到一個數據幀DF,然後將其轉換成numpy的陣列

df=np.array(df) 

上述所有的偉大工程,是相當快的。不過,後來我用datetime.strptime(第0列是時間戳)

df[:,0]=[(datetime.strptime(str(d),'%H:%M:%S.%f')).total_seconds() for d in df[:,0]] 

的時間戳轉換成秒,不幸的是這原來是veryyyy慢。這不是重複了所有行,這麼慢,但

datetime.strptime 

是瓶頸。有沒有更好的方法來做到這一點?

+1

你是如何確定'datetime.strptime'是瓶頸?我不確定'df [:,0]是不是一個複製片(對numpy不夠熟悉),但是複製片和複製列表看起來更適合我。 –

回答

2

我猜的datetime對象有很大的開銷 - 這可能是更容易做手工:

def to_seconds(s): 
    hr, min, sec = [float(x) for x in s.split(':')] 
    return hr*3600 + min*60 + sec 
+0

這將引發一個'ValueError',因爲您將在最後一個位置的數字的十進制表示形式上調用'int'。根據OP的問題,輸入格式爲'11:52:55.162'。 –

+0

@ Two-BitAlchemist我糾正了,我改變它浮動。 –

+0

很多。是的,這要快得多。感謝您的快速回復! – fact

0

使用sum()enumerate() -

>>> ts = '11:52:55.162' 
>>> ts1 = map(float, ts.split(':')) 
>>> ts1 
[11.0, 52.0, 55.162] 
>>> ts2 = [60**(2-i)*n for i, n in enumerate(ts1)] 
>>> ts2 
[39600.0, 3120.0, 55.162] 
>>> ts3 = sum(ts2) 
>>> ts3 
42775.162 
>>> seconds = sum(60**(2-i)*n for i, n in enumerate(map(float, ts.split(':')))) 
>>> seconds 
42775.162 
>>> 
+1

這是一個非常繁瑣的方式執行這樣一個簡單的事情.. –

+0

我已經做到了這兩種方式(你的和我的),事實證明你的速度更快,即使與函數調用。 – wwii

3

這裏,使用timedeltas

創建樣本系列

In [21]: s = pd.to_timedelta(np.arange(100000),unit='s') 

In [22]: s 
Out[22]: 
0 00:00:00 
1 00:00:01 
2 00:00:02 
3 00:00:03 
4 00:00:04 
5 00:00:05 
6 00:00:06 
7 00:00:07 
8 00:00:08 
9 00:00:09 
10 00:00:10 
11 00:00:11 
12 00:00:12 
13 00:00:13 
14 00:00:14 
... 
99985 1 days, 03:46:25 
99986 1 days, 03:46:26 
99987 1 days, 03:46:27 
99988 1 days, 03:46:28 
99989 1 days, 03:46:29 
99990 1 days, 03:46:30 
99991 1 days, 03:46:31 
99992 1 days, 03:46:32 
99993 1 days, 03:46:33 
99994 1 days, 03:46:34 
99995 1 days, 03:46:35 
99996 1 days, 03:46:36 
99997 1 days, 03:46:37 
99998 1 days, 03:46:38 
99999 1 days, 03:46:39 
Length: 100000, dtype: timedelta64[ns] 

轉換爲字符串,用於測試目的

In [23]: t = s.apply(pd.tslib.repr_timedelta64) 

這些都是字符串

In [24]: t.iloc[-1] 
Out[24]: '1 days, 03:46:39' 

除以一個timedelta64將其轉換爲秒

In [25]: pd.to_timedelta(t.iloc[-1])/np.timedelta64(1,'s') 
Out[25]: 99999.0 

這是目前配套使用REG -ex,所以從字符串中直接得到的不是很快。

In [27]: %timeit pd.to_timedelta(t)/np.timedelta64(1,'s') 
1 loops, best of 3: 1.84 s per loop 

這是一個基於日期的時間戳SOLN

由於日期時間已存儲的Int64的,這是很容易的快速

創建一個樣品系列

In [7]: s = Series(date_range('20130101',periods=1000,freq='ms')) 

In [8]: s 
Out[8]: 
0   2013-01-01 00:00:00 
1 2013-01-01 00:00:00.001000 
2 2013-01-01 00:00:00.002000 
3 2013-01-01 00:00:00.003000 
4 2013-01-01 00:00:00.004000 
5 2013-01-01 00:00:00.005000 
6 2013-01-01 00:00:00.006000 
7 2013-01-01 00:00:00.007000 
8 2013-01-01 00:00:00.008000 
9 2013-01-01 00:00:00.009000 
10 2013-01-01 00:00:00.010000 
11 2013-01-01 00:00:00.011000 
12 2013-01-01 00:00:00.012000 
13 2013-01-01 00:00:00.013000 
14 2013-01-01 00:00:00.014000 
... 
985 2013-01-01 00:00:00.985000 
986 2013-01-01 00:00:00.986000 
987 2013-01-01 00:00:00.987000 
988 2013-01-01 00:00:00.988000 
989 2013-01-01 00:00:00.989000 
990 2013-01-01 00:00:00.990000 
991 2013-01-01 00:00:00.991000 
992 2013-01-01 00:00:00.992000 
993 2013-01-01 00:00:00.993000 
994 2013-01-01 00:00:00.994000 
995 2013-01-01 00:00:00.995000 
996 2013-01-01 00:00:00.996000 
997 2013-01-01 00:00:00.997000 
998 2013-01-01 00:00:00.998000 
999 2013-01-01 00:00:00.999000 
Length: 1000, dtype: datetime64[ns] 

轉換爲ns自epoch/div除以得到毫秒自紀元(如果你想秒, 除以10 ** 9)

In [9]: pd.DatetimeIndex(s).asi8/10**6 
Out[9]: 
array([1356998400000, 1356998400001, 1356998400002, 1356998400003, 
     1356998400004, 1356998400005, 1356998400006, 1356998400007, 
     1356998400008, 1356998400009, 1356998400010, 1356998400011, 
     ... 
     1356998400992, 1356998400993, 1356998400994, 1356998400995, 
     1356998400996, 1356998400997, 1356998400998, 1356998400999]) 

相當快

In [12]: s = Series(date_range('20130101',periods=1000000,freq='ms')) 

In [13]: %timeit pd.DatetimeIndex(s).asi8/10**6 
100 loops, best of 3: 11 ms per loop 
+0

我認爲這裏的瓶頸是創建日期時間對象,而不是計算總秒數。 –

相關問題