我有一个函数,为每个用户(4000个用户)找到一个给定列表(一个列表)和其他列表(60,000个列表)之间的常见,不常见项目及其费率。 运行以下循环需要太长的时间和高内存使用率,部分列表构造和崩溃。 我认为由于返回的列表很长,而且元素(元组)很重,所以我将它分成了两个函数,如下所示,但是在元组中添加列表项时似乎有问题,[(user,[items],rate),(user,[items],rate),...]
。 我想从返回的值创建一个数据帧,
我应该对一个算法做些什么来绕过这件事并减少内存使用?
我正在使用python 3.7,windows 10,64位,RAM 8g。
常用项功能:
def common_items(user,list1, list2):
com_items = list(set(list1).intersection(set(list2)))
com_items_rate = len(com_items)/len(set(list1).union(set(list2)))
return user, com_items, com_items_rate
不常用项功能:
def uncommon_items(user,list1, list2):
com_items = list(set(list1).intersection(set(list2)))
com_items_rate = len(com_items)/len(set(list1).union(set(list2)))
uncom_items = list(set(list2) - set(com_items)) # uncommon items that blonge to list2
uncom_items_rate = len(uncom_items)/len(set(list1).union(set(list2)))
return user, com_items_rate, uncom_items, uncom_items_rate # common_items_rate is also needed
构建列表:
common_item_rate_tuple_list = []
for usr in users: # users.shape = 4,000
list1 = get_user_list(usr) # a function to get list1, it takes 0:00:00.015632 or less for a user
# print(usr, len(list1))
for list2 in df["list2"]: # df.shape = 60,000
common_item_rate_tuple = common_items(usr,list1, list2)
common_item_rate_tuple_list.append(common_item_rate_tuple)
print(len(common_item_rate_tuple_list)) # 4,000 * 60,000 = 240,000,000 items
# sample of common_item_rate_tuple_list:
#[(1,[2,5,8], 0.676), (1,[7,4], 0.788), ....(4000,[1,5,7,9],0.318), (4000,[8,9,6],0.521)
我看了(记忆错误和列表限制?) 和(在Python中追加到列表时的内存错误),它们处理的是构造的列表。 我无法处理建议的答案(Python列表内存错误)。
对于这么大的数据,您应该考虑几件事情来实现速度和内存管理。
集
,因为顺序在列表中没有意义,而且您正在进行许多集的相交。 那么,是否可以更改get_user_list()
函数以返回集合而不是列表呢? 这将防止所有不必要的转换你正在做。 与清单2相同,只需立即创建一个集合