首页 > 解决方案 > 一系列列表的元素随机选择(没有循环)

问题描述

我想从一系列列表中的每个列表中随机选择一个元素。

import pandas as pd
import numpy as np

l=[['a','b','c'],['d','e','f'],['g','h','i'],['j','k','l'],['m','n','o']]
s = pd.Series(l)

也是这样s

0    [a, b, c]
1    [d, e, f]
2    [g, h, i]
3    [j, k, l]
4    [m, n, o]
dtype: object

我知道我可以做到以下几点:

s = pd.Series([np.random.choice(i) for i in s])

哪个有效:

0    a
1    e
2    h
3    j
4    m
dtype: object

但我想知道是否有一种非循环方法可以做到这一点?

例如,(假设每个list大小相等)您可以创建一个随机索引数组来尝试从每个索引中选择不同的元素list

i = np.random.randint(3, size=len(l))
#array([2, 2, 0, 1, 0])

但是做 says[i]不起作用,因为那是索引s而不是应用于 each list

2    [g, h, i]
2    [g, h, i]
0    [a, b, c]
1    [d, e, f]
0    [a, b, c]
dtype: object

我的动机是拥有可以在大量列表上工作的东西,从而避免循环。但是,如果我的列表理解似乎是最合理的,或者没有内置pandas/numpy函数,请告诉我。

标签: pythonpandaslistnumpy

解决方案


我只能这样想,但是,性能可能是问题

np.array(s.tolist())[np.arange(len(s)), np.random.randint(3, size=len(s))]
array(['c', 'e', 'i', 'k', 'n'], dtype='<U1')

一些时机

%timeit s.explode().sample(frac=1, random_state=1) 
5.05 ms ± 294 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit pd.Series([np.random.choice(i) for i in s])
23.1 ms ± 184 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit np.array(s.tolist())[np.arange(len(s)), np.random.randint(3, size=len(s))]
1.63 ms ± 50.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

推荐阅读