Python - 根据另一个列表的唯一元素从一个列表中随机抽取一个元素
Python - Sample one element randomly from a list based on the unique elements of another list
我有 2 个列表,其中包含 user_ids
和 item_ids
。我想为每个用户随机抽样一件商品。
例如
user_ids = [1,2,3 ,1, 2]
item ids = [8,9,10,5,8]
我想得到-
val_user_ids = [1,2,3]
val_item_ids = [5,9,10]
我知道一些低效的方法,比如循环等等。
有什么有效的方法吗?或者是否存在相同的 python 函数?
准确地说,我想创建一个验证集(来自训练集),其中包含每个用户的 1 个项目交互。
你会用 numpy 吗?示例代码为:
import numpy as np
idx = list(range(your_list_size))
# make random draw based your validation size
val_size = 0.2
val_n = int(your_list_size*val_size)
# draw sample from user and item list, replace=False means no replacement
chosen_idx = np.random.choice(idx, size=val_n, replace=False)
# get actual values by chosen idx
sample_users = np.array(user_ids)[chosen_idx]
sample_items = np.array(item_ids)[chosen_idx]
或者甚至简单地执行以下操作:
sample_users = np.random.choice(user_ids, size=val_n, replace=False)
sample_items = np.random.choice(items_ids, size=val_n, replace=False)
假设物品需要放回抽样,下面的代码可以工作:
import random
user_ids = [1,2,3,1,2]
item_ids = [8,9,10,5,8]
val_user_ids = sorted(set(user_ids))
val_item_ids = [random.choice(item_ids) for item in val_user_ids]
set 内置函数 returns 来自像列表这样的可迭代对象的集合(唯一项),然后是 sorted 内置函数 returns 一个排序列表(如果你不需要排序,直接用list(set(user_ids))
)。然后列表理解创建(通常比 for 循环在执行速度方面更有效)一个新列表,其中包含从 item_ids 中采样的项目,并进行替换。一个警告:user_id 列表需要包含不可变项才能使此代码正常工作(数字很好,字符串、冻结集和元组也可以,只要元组不包含像列表这样的可变结构)。
如果您需要在不放回的情况下进行采样,您可以使用:
import random
user_ids = [1,2,3 ,1, 2]
item_ids = [8,9,10,5,8]
val_user_ids = sorted(set(user_ids))
random.shuffle(item_ids)
val_item_ids = [item_ids.pop(i) for i in range(len(val_user_ids))]
关于应用集的相同警告(不能包含任何可变内容)。
您可以将数据收集到字典中,以 user_id 作为键,以列表中的 item_ids 作为值
import collections
user_ids = [1, 2, 3, 1, 2]
item_ids = [8, 9, 10, 5, 8]
data = collections.defaultdict(list)
for key, value in zip(user_ids, item_ids):
data[key].append(value)
结果是defaultdict(<class 'list'>, {1: [8, 5], 2: [9, 8], 3: [10]})
。
现在我们可以遍历字典并从列表中随机获取一个项目。
import random
result = [(key, random.choice(value)) for key, value in data.items()]
结果是 [(1, 8), (2, 9), (3, 10)]
(或 [(1, 8), (2, 8), (3, 10)]
或随机化给我们的任何结果)。
关于 defaultdict
的更多信息。这种字典如果不存在就会创建一个默认项。默认值在创建 defaultdict
时作为参数给出。使用标准 dict
我们必须自己处理条目的创建。
这是手动完成的方式:
user_ids = [1, 2, 3, 1, 2]
item_ids = [8, 9, 10, 5, 8]
data = dict()
for key, value in zip(user_ids, item_ids):
if key not in data:
data[key] = []
data[key].append(value)
我有 2 个列表,其中包含 user_ids
和 item_ids
。我想为每个用户随机抽样一件商品。
例如
user_ids = [1,2,3 ,1, 2]
item ids = [8,9,10,5,8]
我想得到-
val_user_ids = [1,2,3]
val_item_ids = [5,9,10]
我知道一些低效的方法,比如循环等等。 有什么有效的方法吗?或者是否存在相同的 python 函数?
准确地说,我想创建一个验证集(来自训练集),其中包含每个用户的 1 个项目交互。
你会用 numpy 吗?示例代码为:
import numpy as np
idx = list(range(your_list_size))
# make random draw based your validation size
val_size = 0.2
val_n = int(your_list_size*val_size)
# draw sample from user and item list, replace=False means no replacement
chosen_idx = np.random.choice(idx, size=val_n, replace=False)
# get actual values by chosen idx
sample_users = np.array(user_ids)[chosen_idx]
sample_items = np.array(item_ids)[chosen_idx]
或者甚至简单地执行以下操作:
sample_users = np.random.choice(user_ids, size=val_n, replace=False)
sample_items = np.random.choice(items_ids, size=val_n, replace=False)
假设物品需要放回抽样,下面的代码可以工作:
import random
user_ids = [1,2,3,1,2]
item_ids = [8,9,10,5,8]
val_user_ids = sorted(set(user_ids))
val_item_ids = [random.choice(item_ids) for item in val_user_ids]
set 内置函数 returns 来自像列表这样的可迭代对象的集合(唯一项),然后是 sorted 内置函数 returns 一个排序列表(如果你不需要排序,直接用list(set(user_ids))
)。然后列表理解创建(通常比 for 循环在执行速度方面更有效)一个新列表,其中包含从 item_ids 中采样的项目,并进行替换。一个警告:user_id 列表需要包含不可变项才能使此代码正常工作(数字很好,字符串、冻结集和元组也可以,只要元组不包含像列表这样的可变结构)。
如果您需要在不放回的情况下进行采样,您可以使用:
import random
user_ids = [1,2,3 ,1, 2]
item_ids = [8,9,10,5,8]
val_user_ids = sorted(set(user_ids))
random.shuffle(item_ids)
val_item_ids = [item_ids.pop(i) for i in range(len(val_user_ids))]
关于应用集的相同警告(不能包含任何可变内容)。
您可以将数据收集到字典中,以 user_id 作为键,以列表中的 item_ids 作为值
import collections
user_ids = [1, 2, 3, 1, 2]
item_ids = [8, 9, 10, 5, 8]
data = collections.defaultdict(list)
for key, value in zip(user_ids, item_ids):
data[key].append(value)
结果是defaultdict(<class 'list'>, {1: [8, 5], 2: [9, 8], 3: [10]})
。
现在我们可以遍历字典并从列表中随机获取一个项目。
import random
result = [(key, random.choice(value)) for key, value in data.items()]
结果是 [(1, 8), (2, 9), (3, 10)]
(或 [(1, 8), (2, 8), (3, 10)]
或随机化给我们的任何结果)。
关于 defaultdict
的更多信息。这种字典如果不存在就会创建一个默认项。默认值在创建 defaultdict
时作为参数给出。使用标准 dict
我们必须自己处理条目的创建。
这是手动完成的方式:
user_ids = [1, 2, 3, 1, 2]
item_ids = [8, 9, 10, 5, 8]
data = dict()
for key, value in zip(user_ids, item_ids):
if key not in data:
data[key] = []
data[key].append(value)