如何制作一个 for-loop,迭代超过 1500 万条记录,space-高效?
How to make a for-loop, which iterates over 15mln records, space-efficient?
我对简单的 for 循环有疑问。我正在尝试从列表(即移位列表 windows)中计算最大值,创建这些最大值的列表,稍后我会将其添加到数据框中。
我的数据框有两列浮点值和日期时间索引。数据文件有大约 1500 万行(即我要迭代的系列的长度是 1500 万)(700 MB)。
当我 运行 我的简单循环一段时间后,我的计算机 运行 内存不足并崩溃。我有 12 GB 的内存。
我的代码:
import pandas as pd
import numpy as np
# sample data
speed = np.random.uniform(0,25,15000000)
data_dict = {'speed': speed}
df = pd.DataFrame(data_dict)
# create a list of 'windows', i.e. subseries of the list
def GetShiftingWindows(thelist, size):
return [ thelist[x:x+size] for x in range( len(thelist) - size + 1 ) ]
window_size = 10
list_of_win_speeds = GetShiftingWindows(df.speed, window_size)
list_of_max_speeds = []
for x in list_of_win_speeds:
max_value = max(x)
list_of_max_speeds.append(max_value)
我不是CS专业的。在我看来,这是一个 space-复杂性问题。为了使计算可行,我在这里缺少什么?
作为第一步,我会改变
return [ thelist[x:x+size] for x in range( len(thelist) - size + 1 ) ]
进入
return ( thelist[x:x+size] for x in range( len(thelist) - size + 1 ) )
然后你将得到一个生成器,你的代码在内存中创建整个子列表列表,生成器方法将在每个 for
迭代中只生成一个子列表
如果您使用 Python 2,您还可以将 range
(一次生成整个列表)更改为 xrange
(生成器每次调用只生成一个值)
最后你可以 return 使用 islice
:
的迭代器生成器
from itertools import islice
和
return ( islice(thelist, x, x + size) for x in range( len(thelist) - size + 1 ) )
首先,您应该使用 pandas 聚合函数,而不是尝试遍历列表并自行完成。目前还不清楚这个函数究竟应该做什么:
def GetShiftingWindows(thelist, size):
return [ thelist[x:x+size] for x in range( len(thelist) - size + 1 ) ]
但它所做的是创建一个非常大的字典。考虑投资 yield。当你使用 yield 时,你并没有将这个大字典存储在内存中。
def GetShiftingWindows(thelist, size):
for x in range( len(thelist) - size + 1 ):
yield thelist[x:x+size]
你可以使用xrange() instead of range()再挤出几个字节。
yield 和xrange 的优点是它不在内存中存储列表。而是生成一个延迟计算的迭代器,它具有更小的内存需求。
我对简单的 for 循环有疑问。我正在尝试从列表(即移位列表 windows)中计算最大值,创建这些最大值的列表,稍后我会将其添加到数据框中。
我的数据框有两列浮点值和日期时间索引。数据文件有大约 1500 万行(即我要迭代的系列的长度是 1500 万)(700 MB)。
当我 运行 我的简单循环一段时间后,我的计算机 运行 内存不足并崩溃。我有 12 GB 的内存。
我的代码:
import pandas as pd
import numpy as np
# sample data
speed = np.random.uniform(0,25,15000000)
data_dict = {'speed': speed}
df = pd.DataFrame(data_dict)
# create a list of 'windows', i.e. subseries of the list
def GetShiftingWindows(thelist, size):
return [ thelist[x:x+size] for x in range( len(thelist) - size + 1 ) ]
window_size = 10
list_of_win_speeds = GetShiftingWindows(df.speed, window_size)
list_of_max_speeds = []
for x in list_of_win_speeds:
max_value = max(x)
list_of_max_speeds.append(max_value)
我不是CS专业的。在我看来,这是一个 space-复杂性问题。为了使计算可行,我在这里缺少什么?
作为第一步,我会改变
return [ thelist[x:x+size] for x in range( len(thelist) - size + 1 ) ]
进入
return ( thelist[x:x+size] for x in range( len(thelist) - size + 1 ) )
然后你将得到一个生成器,你的代码在内存中创建整个子列表列表,生成器方法将在每个 for
迭代中只生成一个子列表
如果您使用 Python 2,您还可以将 range
(一次生成整个列表)更改为 xrange
(生成器每次调用只生成一个值)
最后你可以 return 使用 islice
:
from itertools import islice
和
return ( islice(thelist, x, x + size) for x in range( len(thelist) - size + 1 ) )
首先,您应该使用 pandas 聚合函数,而不是尝试遍历列表并自行完成。目前还不清楚这个函数究竟应该做什么:
def GetShiftingWindows(thelist, size):
return [ thelist[x:x+size] for x in range( len(thelist) - size + 1 ) ]
但它所做的是创建一个非常大的字典。考虑投资 yield。当你使用 yield 时,你并没有将这个大字典存储在内存中。
def GetShiftingWindows(thelist, size):
for x in range( len(thelist) - size + 1 ):
yield thelist[x:x+size]
你可以使用xrange() instead of range()再挤出几个字节。
yield 和xrange 的优点是它不在内存中存储列表。而是生成一个延迟计算的迭代器,它具有更小的内存需求。