繁体   English   中英

Python - 根据另一个列表的唯一元素从一个列表中随机采样一个元素

[英]Python - Sample one element randomly from a list based on the unique elements of another list

我有 2 个包含user_idsitem_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 function?

准确地说,我想为每个用户创建一个包含 1 个项目交互的验证集(来自训练集)。

您可以在字典中收集数据,其中 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)

你能用 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 内置从一个可迭代的列表中返回一个集合(唯一项),然后 sorted 内置 function 返回一个排序列表(如果不需要排序,只需使用list(set(user_ids)) )。 然后列表推导式创建(在执行速度方面通常比 for 循环更有效)一个新列表,其中包含从 item_ids 采样的项目,并进行替换。 一个警告:user_id 列表需要包含不可变项才能使此代码正常工作(数字很好,字符串、frozensets 和元组也可以,只要元组不包含列表等可变结构)。

如果您需要在不更换的情况下进行采样,您可以使用:

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))]

关于应用集的相同警告(不能包含任何可变的内容)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM