私は数百万のトランザクションを持つテーブルを持っています。テーブルは、トランザクションのタイムスタンプ、金額、およびいくつかの他のプロパティ(例えば、アドレス)を含む。それぞれの取引について、同じ住所、例えば1ヶ月などの期間内に発生した取引の数と金額の合計を計算したいと考えています。ここでトランザクションログから速度変数を計算する
は、例えば、入力された:
+----+---------------------+----------------+--------+
| id | ts | address | amount |
+----+---------------------+----------------+--------+
| 0 | 2016-10-11 00:34:21 | 123 First St. | 56.20 |
+----+---------------------+----------------+--------+
| 1 | 2016-10-13 02:53:58 | 456 Second St. | 96.19 |
+----+---------------------+----------------+--------+
| 2 | 2016-10-23 02:28:17 | 123 First St. | 64.65 |
+----+---------------------+----------------+--------+
| 3 | 2016-10-31 07:14:35 | 456 Second St. | 36.38 |
+----+---------------------+----------------+--------+
| 4 | 2016-11-04 09:25:39 | 123 First St. | 93.65 |
+----+---------------------+----------------+--------+
| 5 | 2016-11-20 22:30:15 | 123 First St. | 88.39 |
+----+---------------------+----------------+--------+
| 6 | 2016-11-28 09:39:14 | 123 First St. | 74.40 |
+----+---------------------+----------------+--------+
| 7 | 2016-12-03 17:09:12 | 123 First St. | 83.13 |
+----+---------------------+----------------+--------+
これはすべき出力:
+----+-------+--------+
| id | count | amount |
+----+-------+--------+
| 0 | 0 | 0.00 |
+----+-------+--------+
| 1 | 0 | 0.00 |
+----+-------+--------+
| 2 | 1 | 56.20 |
+----+-------+--------+
| 3 | 1 | 96.19 |
+----+-------+--------+
| 4 | 2 | 120.85 |
+----+-------+--------+
| 5 | 1 | 64.65 |
+----+-------+--------+
| 6 | 1 | 88.39 |
+----+-------+--------+
| 7 | 2 | 162.79 |
+----+-------+--------+
これを行うために、私は、タイムスタンプでテーブルをソートして、私は基本的にキューや辞書を使用していますしかし、それは本当に遅く実行されているようだ、私はそれを行うより良い方法があるのだろうかと思っていた。ここで
が私のコードです:
import csv
import Queue
import time
props = [ 'address', ... ]
spans = { '1m': 2629800, ... }
h = [ 'id' ]
for value in [ 'count', 'amount' ]:
for span in spans:
for prop in props:
h.append(span + '_' + prop + '_' + value)
tq = { }
kq = { }
vq = { }
for span in spans:
tq[span] = Queue.Queue()
kq[span] = { }
vq[span] = { }
for prop in props:
kq[span][prop] = Queue.Queue()
vq[span][prop] = { }
with open('transactions.csv', 'r') as csvin, open('velocities.csv', 'w') as csvout:
reader = csv.DictReader(csvin)
writer = csv.DictWriter(csvout, h)
writer.writeheader()
for i in reader:
o = { 'id': i['id'] }
ts = time.mktime(time.strptime(i['ts'], '%Y-%m-%d %H:%M:%S'))
for span in spans:
while not tq[span].empty() and ts > tq[span].queue[0] + spans[span]:
tq[span].get()
for prop in props:
key = kq[span][prop].get()
vq[span][prop][key].get()
if vq[span][prop][key].empty():
del vq[span][prop][key]
tq[span].put(ts)
for prop in props:
kq[span][prop].put(i[prop])
if not i[prop] in vq[span][prop]:
vq[span][prop][i[prop]] = Queue.Queue()
o[span + '_' + prop + '_count'] = vq[span][prop][i[prop]].qsize()
o[span + '_' + prop + '_amount'] = sum(vq[span][prop][i[prop]].queue)
vq[span][prop][i[prop]].put(float(i['auth']))
writer.writerow(o)
csvout.flush()
私はまた、RB-木とvq[span][prop]
を交換しようとしたが、パフォーマンスはさらに悪化していました。
私は十分にクリアされていないかもしれません。私がCSV(トランザクション)内の行を処理する場合、カウントと金額は、そのトランザクションの前月以内に発生したすべてのトランザクション(たとえば、そのプロパティを共有しているすべてのトランザクション)例えば、同じアドレスを持つ)。 – wizplum
例として、これは、現在のトランザクションの日付が「2016-03-01 10:33:11」で、アドレスが「123 Main St」の場合、2629800まで発生したすべてのトランザクションを反映することを意味しますその前に同じアドレスを持っていました。 – wizplum
二次元でグループ化しているのなら、かなり簡単です。単に 'defaultdict(Counter)'を使用してください。私の例を更新しました。 –