大数据集崩溃了python脚本

时间:2017-08-02 11:58:27

标签: python recursion crash limit grasshopper

我有使用GyPython组件的简单脚本用于Rhino / Grasshopper。目标是将每小时的天气数据(仅记录几小时)分配到几小时。如果没有测量值则返回0.它应该像这样工作(具有相似值的示例):

hoursList = [hr1,hr2,hr3,hr4,hr5,hr6]
measuredList = [hr2,hr3,hr6]
recordList = [wData1,wData2,wData3]
finalList = []    

def assignData(i,y):        
    for i < len(leadList):            
        if hoursList[i] == measuredList[y]:                
            finalList.append(recordList[y])                
            i += 1
            y += 1                
        else:                
            finalList.append(0)                
            i += 1    
        assignData(i,y)    

i = 0
y = 0    
assignData(i,y)

应该返回

[0,wData1,wData2,0,0,wData3]

此案例的结果finalList(添加了换行符以帮助提高可读性)

[0, 'wData1', 'wData2', 0, 0, 'wData3', 'wData3',
 0, 'wData3', 'wData3', 0, 0, 'wData3', 'wData3',
 0, 'wData3', 'wData3', 'wData2', 0, 0, 'wData3', 'wData3',
 0, 'wData3', 'wData3', 0, 0, 'wData3', 'wData3',
 0, 'wData3', 'wData3', 'wData1', 'wData2', 0, 0, 'wData3', 'wData3',
 0, 'wData3', 'wData3', 0, 0, 'wData3', 'wData3',
 0, 'wData3', 'wData3', 'wData2', 0, 0, 'wData3', 'wData3',
 0, 'wData3', 'wData3', 0, 0, 'wData3', 'wData3',
 0, 'wData3', 'wData3']

当我尝试在大数据列表上运行此代码(大约43000个值)时,它会在大约7000次迭代后崩溃。我检查了sys.getrecursionlimit和它的2147483647.任何想法如何让这项工作?

1 个答案:

答案 0 :(得分:2)

<强>分析

我认为len(leadList)是你提供的43000个数字。我将此称为limit

注意你的循环是如何工作的:对于&#34;输入i&#34;范围内的i的每个值。到limit,这会处理一个项目,递增i(也许y),然后重复。因此,您在i=0的顶级呼叫将产生对assignData(1, 0)的呼叫(假设失败)并等待该呼叫完成。然后它将回到循环的顶部,使用i = 1,并继续...最终连续产生limit递归调用。

该初始调用现在将适用于范围(1,限制),产生limit-1个调用,其中第一个将产生limit-2个调用,依此类推。每个级别都会产生另一个级别,并有一个大扇出。

简而言之,您产生的电话远远超出我的想象;随着你增加limit,总数会快速增长。

我怀疑你的问题是finalList只是超出了可用内存,因为每个调用都追加一个元素。

<强>研究

将基本调试语句插入代码中:

def assignData(i, y):
    print "ENTER", i, y, finalList
    for i < len(leadList):
        ...

所以你可以看到电话的进展。

<强> REPAIR

我怀疑你需要这个双重嵌套的递归堆栈。事实上,我没有看到递归会给你带来任何好处。看起来好像只需要遍历列表一次,查找实际对应的时间,否则填写0。摆脱呼叫,正确使用for来控制i的值,并根据需要削减代码。

def assignData():
    y = 0        
    for i in range(0, len(leadList)):            
        if hoursList[i] == measuredList[y]:                
            finalList.append(recordList[y])                
            y += 1                
        else:                
            finalList.append(0)

更好的解决方案

如果你需要的只是匹配时间的记录,你可以更直接地做到这一点。建立一个字典来记录时间的测量结果。

meas = dict(zip(measuredList, recordList)

现在,写一个列表推导来插入0,不在字典中。

finalList = [meas[time] if time in meas else 0
                for time in hourslist]

如果我正确地阅读了您的问题,那就是您的总体目标。