2013-06-20 18 views
4

我有時間線/時間序列,它由一個二元組列表組成,其中元組的第一部分是時間戳,第二部分是值。元組按他們的時間戳排序。加入兩個時間表/元組列表

我現在有兩個時間表,需要將它們相互分開。這意味着如果我在兩個時間軸上獲得相同時間戳的值,我需要將它們分開。如果時間戳中的某個時間軸上沒有值,則應假定爲0。如果(且僅當)除以零時發生,則應該假定NaN。時間戳有很大的差距,這意味着從min(timestamp)到max(timestamp)的迭代不是解決方案。

我構建的解決方案既非常和諧,運行時間也很差。由於時間表大約有一百萬條記錄,因此性能對我來說很重要。我的解決方案沒有利用,兩個列表都已排序。

有沒有更好的解決方案,如果是的,哪個?

#!/usr/bin/env python 

l1 = [(1, 100), (2, 1000),   (4, 1500), (5, 5400),   (7, 7800)] 
l2 = [(1, 20), (2, 400), (3, 240), (4, 500), (5, 100), (6, 27),   ] 
ex = [(1, 5), (2, 2), (3, 0), (4, 3), (5, 54), (6, 0), (7, float('NaN'))] 

def f(l1, l2): 
    #Turn to dicts: 
    l1d = dict(l1) 
    l2d = dict(l2) 

    #Compute Keyspace 
    keys = set(l1d.keys()).union(set(l2d.keys())) 

    result = [] 
    for key in keys: 
    if not key in l2d: 
     result.append((key, float('NaN'))) 
    elif key not in l1d: 
     result.append((key, 0)) 
    else: 
     result.append((key, l1d[key]/l2d[key])) 

    return result 

r = f(l1, l2) 

print("L1: %s" % (l1)) 
print("L2: %s" % (l2)) 
print("") 
print("Expected: %s" % (ex)) 
print("Result: %s" % (r)) 
+0

哪個python版本? – jamylak

+0

可以說2.7,但我願意切換到3的表現。 – theomega

+0

您可以重複使用列表進行排序並一次迭代一個步驟的事實。不太確定寫這個的pythonic方式是什麼。 – Josay

回答

3

如果需要的性能,看看pandas

import pandas as pd 

l1 = [(1, 100), (2, 1000),   (4, 1500), (5, 5400),   (7, 7800)] 
l2 = [(1, 20), (2, 400), (3, 240), (4, 500), (5, 100), (6, 27),   ] 

s1 = pd.Series(dict(l1)) 
s2 = pd.Series(dict(l2)) 

現在非常明確的數學運算:

s1/s2 

回報

1  5.0 
2  2.5 
3  NaN 
4  3.0 
5 54.0 
6  NaN 
7  NaN 

如果你想取代NaN用零如果出現在l2

s1.reindex(s1.index|s2.index).fillna(0)/s2 


1  5.0 
2  2.5 
3  0.0 
4  3.0 
5 54.0 
6  0.0 
7  NaN 

完全可以很好地用於萬個條目爲好。您可以在索引中使用日期時間並在日期時間對其進行操作。

+0

謝謝!我需要區分0和NaN:0是否在第一組中丟失,而第二組是NaN。我會更新我的問題。 – theomega

+0

@theomega - 我爲你的情況更新了我的答案。 – eumiro