簡體   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