これは私の最初の質問ですので、間違いを許してください。Python:必要なデータセットを見つけるための多対多の比較
私は、次の例のようにいくつかの情報(〜10000000 +)線で大きなファイル(CSV)持っている:私の目標は、各行を読んで、箱の体積を計算し、1以内です
date;box_id;box_length;box_width;box_height;weight;type
--snip--
1999-01-01 00:00:20;nx1124;10;4;5.5;2.1;oversea
1999-01-01 00:00:20;np11r4;8;3.25;2;4.666;local
--snip--
を(たとえば、00:00:00 - 00:00:59)2つ以上のボックスの音量が類似している場合(+ 10%の差異)、録音してからタイムスタンプとタイプを記録する必要があります。現時点で
、私はブルートフォースアプローチを使用しています。各回線を通じて
- 実行が
- 繰り返しを比較します1時間の時間差が検出されるまで
- リストから最初のボックスを削除する
- 私の1時間ウィンドウが1,2,3,4を持っている場合 例えば
、私はこの
1
2 == 1
3 == 1 then == 2
4 == 1 then == 2 then == 3
5 == 2 then == 3 then == 4 # removed 1 from list(1hr window moved down)
6 == 2 then == 3 then == 4 then == 5
7 == 2 then == 3 then == 4 then == 5 then == 6
.... so on ....
をやっている2番目のボックスで、リストにこれは、私が考えている最高のものです。なぜなら、各ボックスを、指定された時間枠内の他のものとそれぞれ比較する必要があるからです。しかし、これは現時点では非常に遅いです。
私はより良いアルゴリズムを探していますが、どの方向に向かうべきかはわかりません。私はいくつかの優れたツール(これまでのところ、Pandasは私のお気に入りです)を学ぼうとしていますが、必要な方法でこれらのツールがデータを処理できるようにするためのアルゴリズムを実装する必要があると仮定しています。
もし私が私のpythonコード(ソース)を投稿するのに役立ちます。
更新以下は私のコードです。私はいくつかの行(try/catchブロックなど、無効なファイルパス/形式、型変換エラー処理など)を省略しました。私は5秒のウィンドウのために少し作業するコードをカスタマイズしました。続き
は、比較を行う実際のプログラムで続いてBoxクラス
from datetime import datetime
from time import mktime
class Box(object):
""" Box model """
def __init__(self,data_set):
self.date = data_set[0]
self.timestamp = self.__get_time()
self.id = data_set[1]
self.length = float(data_set[2])
self.width = float(data_set[3])
self.height = float(data_set[4])
self.weight = int(data_set[5])
self.volume = self.__get_volume()
def __get_time(self):
""" convert from date string to unix-timestamp """
str_format = '%Y-%m-%d %H:%M:%S'
t_tuple = datetime.strptime(self.date, str_format).timetuple()
return mktime(t_tuple)
def __get_volume(self):
""" calculate volume of the box """
return (self.length * self.width * self.height)
です。私は便宜のためユーティリティファイルとmain.pyファイルを一緒に組み合わせました。
from csv import reader
from io import open as open_file
from os import path
from sys import argv, exit
from time import time
# custom lib
from Box import Box
def main():
file_name = str.strip(argv[1])
boxes_5s = []
diff = 0
similar_boxes = []
for row in get_file(file_name):
if row:
box = Box(row)
if len(boxes_5s) > 0:
diff = box.timestamp - boxes_5s[0].timestamp
if diff < 6:
boxes_5s.append(box)
else:
similar_boxes += get_similar(boxes_5s)
del boxes_5s[0] # remove the oldest box
boxes_5s.append(box)
else:
boxes_5s.append(box)
print(similar_boxes)
def get_file(file_name):
""" open and return csv file pointer line by line """
with open_file(file_name,'rb') as f:
header = f.readline()
print(header)
rows = reader(f, delimiter=';')
for r in rows:
yield r
else:
yield ''
def get_similar(box_list):
""" compare boxes for similar volume """
num_boxes = len(box_list)
similar_boxes = []
record_str = "Box#{} Volm:{} and #{} Volm:{}"
for i in xrange(num_boxes):
box_1 = box_list[i]
for j in xrange(i+1, num_boxes):
box_2 = box_list[j]
vol_diff = abs((box_1.volume - box_2.volume)/box_1.volume) <= 0.1
if vol_diff: similar_boxes.append(record_str.format(box_1.id,box_1.volume,box_2.id, box_2.volume))
return similar_boxes
if __name__ == "__main__":
main()
ありがとうございます。
おそらくそれらを最初に注文してから似たようなボックスを見つけてください。 – armonge
それが役に立ちます。 [最小限の、完全で検証可能なサンプルを作成する方法](http://stackoverflow.com/help/mcve/) – rll
私の質問の漠然とした性質のために申し訳ありません、私は後で私はいくつかのコードを投稿します家 –