如何在python中更有效地搜索大型列表?

时间:2013-08-29 05:59:26

标签: python mysql

问题:我正在处理一个需要迭代的非常大的数据集。每五分钟,我的程序会添加大约1300行信息​​,每行包含4列。这意味着在一天的过程中,它每天收集大约374,400行信息​​或1,497,600个单元格。有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

我正在尝试在每个独特项目的库存水平中记录当天的变化。我当前的技术从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秒。这意味着整天需要大约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。正确?

2 个答案:

答案 0 :(得分:2)

对不起,就目前的形式而言,这看起来非常可怕。

首先,计算结果似乎取决于运行它们的时间。你从昨天开始计算一些东西,而不仅仅是昨天。这是今天的记录(在运行脚本之前插入),今天和明天都会处理。

其次,您似乎遍历整个数据集len(item_names)次,即迭代1.5米行的1300倍!为什么不使用defaultdictCounter

在单次迭代中进行处理

第三,最好使用整数值进行操作,而不是比较项目名称字符串。

答案 1 :(得分:1)

为了获得更好的性能,你应该使用mysql编程而不是python编程。

如果你想控制每个表的插入,最好在mysql中使用 trigger 。如果你想在每天结束时(例如)每天都有搜索或任何你想要的东西,你最好使用光标

你可以通过简单的互联网搜索找到很多游标和触发器周围的东西。顺便说一句tutsplus.com,有一些关于它们的简洁干净的教程。