1

問題: 反復処理が必要な非常に大きなデータ セットを扱っています。私のプログラムは 5 分ごとに、それぞれ 4 列の約 1300 行の情報を追加します。これは、1 日で約 374,400 行の情報または 1,497,600 セルを収集することを意味します。プログラムが 5 分ごとに 1300 個の項目を追跡しているため、1300 行あります。例えば:

Item_Name       Price      Quantity_in_Stock        Maximum_Stock_Level
----------
Soap            1.00              10                     10                    
Frogs           1.25              12                     16
Pickled Yogurt  1.35               7                      8
Malodorous Ooze 6.66               6                     66

私は、それぞれのユニークなアイテムの在庫レベルの 1 日の変化を集計しようとしています。私の現在の手法では、mysql サーバーからデータ セット全体を取得します。アイテム名、在庫レベル、最大在庫、および観察日を信頼しています。

q = """SELECT Item_Name,Item_In_Stock,Item_Max,Observation_Date
    FROM DB WHERE
    Observation_Date>DATE_ADD(curdate(),INTERVAL -1 DAY) """ 


try:
    x.execute(q)
    conn.commit()
    valueValue= x.fetchall() # The entire data set
except:
    conn.rollback()

次に、各 Item_Name を繰り返し処理し、各項目について、一致するすべての値を見つけます。

for item in ItemNames:
     matching = [s for s in valueValue if item[0] in s] # item[0] is an item name, i.e. Soap, Frogs, Pickled Yogurt, etc.

その後、その日の購入数を知りたいです。アイテムが再入荷されるため、在庫レベルに変化があるかどうかを確認するために、各時間間隔を前回と比較する必要があるため、これは注意が必要です (最初と最後だけを比較することはできません)。

for item in matching:
    if not tempValue:
        tempValue = item[1] #for first row, set value equal to first row

    if tempValue > item[1]: #if last row greater than current row
        buyCount = buyCount + (item[1]-tempValue) # Add the different to the buyCount (volume sold)
    tempValue = item[1] #set tempValue for next row comparison

この方法は機能しますが、かなり遅いです。ユニークなアイテム (1300 件中) の集計反復ごとに約 2.2 秒の時間を計りました。これは、1 日全体で計算に約 50 分かかることを意味します。できればこの時間を短縮したい。この検索および集計機能を改善するにはどうすればよいですか?

編集: MySQL に次のコードを使用させようとしましたが、実際には python を使用してすべてを並べ替えるよりも遅くなります。

for item in getnameValues: # for each item name execute the following query
    q = """SELECT Item_Name,Item_In_Stock,Item_Max,Observation_Date
       FROM DB WHERE
       Item_Name=%s and Observation_Date>DATE_ADD(curdate(),INTERVAL -1 DAY) """
 try:
    x.execute(q,item[0]) # executes the query for the current item
    conn.commit()
    valueValue= x.fetchall() 

MySQL 内のすべての項目をループして、リストのリストを Python に送り返す方法が必要だと思います。右?

4

2 に答える 2

2

申し訳ありませんが、現在の形では、これはすべて非常に恐ろしく見えます。

まず、計算の結果は実行時間に依存するようです。昨日だけでなく、昨日から現在までの何かを計算します。つまり、今日のレコード (スクリプトを実行する前に挿入される) で、今日と明日に処理されます。

2 番目に、データセット全体の時間を反復しているように見えますlen(item_names)。つまり、1.5m 行を 1300 回反復しています。defaultdictまたはCounterを使用して、単一の反復で処理を実行しないのはなぜですか?

第三に、アイテム名の文字列を比較するのではなく、整数値で操作する方が適切です。

于 2013-08-29T07:58:14.170 に答える
1

パフォーマンスを向上させるには、python プログラミングの代わりに mysql プログラミングを使用する必要があります。

テーブルへの各挿入を制御したい場合は、mysql でトリガーを使用することをお勧めします。そして、(たとえば)毎日の終わりに検索などをしたい場合は、cursorを使用することをお勧めします。

インターネットで簡単に検索するだけで、カーソルとトリガーの両方に関する多くのものを見つけることができます。ちなみに、tutsplus.com には、それらについてのきちんとしたチュートリアルがあります。

于 2013-08-29T06:36:25.390 に答える