大数据集崩溃 python 脚本
Large data set crashes python script
我有一个使用 GyPython 组件的简单脚本 Rhino/Grasshopper。目标是将每小时的天气数据(只记录了一些小时)分配给小时。如果没有测量它 returns 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)
应该return
[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。有什么想法可以让这项工作成功吗?
分析
我猜len(leadList)
就是你给的43000这个数字。我称之为 limit
.
注意你的循环是如何工作的:对于 "input i" 到 limit
范围内的每个 i
值,这处理一个项目,递增 i
(也许y
), 并重复出现。因此,您在 i=0
的顶级调用将产生对 assignData(1, 0)
的调用(假设失败)并等待它完成。然后它将回到循环的顶部,使用 i=1,并继续...最终连续产生 limit
个递归调用。
初始调用现在将在范围 (1, limit) 内工作,生成 limit-1
调用,第一个调用将生成 limit-2
调用,等等。每个级别都会产生另一个具有大扇出的级别。
简而言之,您发出的呼叫比我认为您意识到的要多得多;当你增加 limit
.
时,总数增长得相当快
我怀疑您的问题是 finalList
超出了可用内存,因为这些调用中的每一个都附加了一个元素。
调查
将基本调试语句插入您的代码中:
def assignData(i, y):
print "ENTER", i, y, finalList
for i < len(leadList):
...
这样您就可以看到通话进度。
修复
我怀疑您是否需要这个双重嵌套的递归堆栈。事实上,我不认为递归能给你带来任何好处。看起来您只需要遍历列表一次,找到实际对应的时间,否则填入 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]
如果我正确地解读了你的问题,那就是你的总体目标。
我有一个使用 GyPython 组件的简单脚本 Rhino/Grasshopper。目标是将每小时的天气数据(只记录了一些小时)分配给小时。如果没有测量它 returns 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)
应该return
[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。有什么想法可以让这项工作成功吗?
分析
我猜len(leadList)
就是你给的43000这个数字。我称之为 limit
.
注意你的循环是如何工作的:对于 "input i" 到 limit
范围内的每个 i
值,这处理一个项目,递增 i
(也许y
), 并重复出现。因此,您在 i=0
的顶级调用将产生对 assignData(1, 0)
的调用(假设失败)并等待它完成。然后它将回到循环的顶部,使用 i=1,并继续...最终连续产生 limit
个递归调用。
初始调用现在将在范围 (1, limit) 内工作,生成 limit-1
调用,第一个调用将生成 limit-2
调用,等等。每个级别都会产生另一个具有大扇出的级别。
简而言之,您发出的呼叫比我认为您意识到的要多得多;当你增加 limit
.
我怀疑您的问题是 finalList
超出了可用内存,因为这些调用中的每一个都附加了一个元素。
调查
将基本调试语句插入您的代码中:
def assignData(i, y):
print "ENTER", i, y, finalList
for i < len(leadList):
...
这样您就可以看到通话进度。
修复
我怀疑您是否需要这个双重嵌套的递归堆栈。事实上,我不认为递归能给你带来任何好处。看起来您只需要遍历列表一次,找到实际对应的时间,否则填入 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]
如果我正确地解读了你的问题,那就是你的总体目标。