4

我有时间线/时间序列,其中包含一个双元组列表,其中元组的第一部分是时间戳,第二部分是值。元组按其时间戳排序。

我现在有两个这样的时间线,需要将它们彼此分开。这意味着如果我在两个时间线中获得相同时间戳的值,我需要将它们分开。如果时间戳上的时间线之一没有值,则应假定为 0。如果(且仅当)发生被零除,则应假定为 NaN。时间戳有很大的差距,这意味着从 min(timestamp) 迭代到 max(timestamp) 不是一个解决方案。

我构建了一个解决方案,它既非常非 Python 又运行时间很差。由于时间线大约有一百万个条目,因此性能对我来说很重要。我的解决方案没有利用这两个列表都已排序。

有没有更好的解决方案,如果是的话?

#!/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))
4

1 回答 1

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

也适用于百万条目。您可以在索引中使用日期时间并按日期时间对它们进行操作。

于 2013-06-20T09:11:00.323 回答