在python中从数组的第三列中选择唯一的随机值
我有一个41000x3 numpy数组,我在下面的函数中称之为“sortedlist”。第三列有一组值,其中一些是重复的,另一些不是。我想从第三列(sortedlist[:,2])中获取一个唯一值的样本(没有重复)。我想我可以用numpy.random.sample(sortedlist[:,2],sample\u size)轻松完成这项工作。问题是我想返回的不仅仅是那些值,还有所有三列,在最后一列中,有我从numpy.random.sample获得的随机选择的值 编辑:我所说的唯一值是指我想要选择只出现一次的随机值。如果我有一个数组:在python中从数组的第三列中选择唯一的随机值,python,random,Python,Random,我有一个41000x3 numpy数组,我在下面的函数中称之为“sortedlist”。第三列有一组值,其中一些是重复的,另一些不是。我想从第三列(sortedlist[:,2])中获取一个唯一值的样本(没有重复)。我想我可以用numpy.random.sample(sortedlist[:,2],sample\u size)轻松完成这项工作。问题是我想返回的不仅仅是那些值,还有所有三列,在最后一列中,有我从numpy.random.sample获得的随机选择的值 编辑:我所说的唯一值是指我想要
array = [[0, 6, 2]
[5, 3, 9]
[3, 7, 1]
[5, 3, 2]
[3, 1, 1]
[5, 2, 8]]
我想选择第三列的4个值,我想得到像new_array_1这样的值:
new_array_1 = [[5, 3, 9]
[3, 7, 1]
[5, 3, 2]
[5, 2, 8]]
但我不想要像new_array_2这样的东西,第3列中的两个值是相同的:
new_array_2 = [[5, 3, 9]
[3, 7, 1]
[5, 3, 2]
[3, 1, 1]]
我有选择随机值的代码,但没有第三列中不应该重复的标准
samplesize = 100
rand_sortedlist = sortedlist[np.random.randint(len(sortedlist), size = sample_size),:]]
我正试图通过这样做来强化这个标准
array_index = where( array[:,2] == sample(SelectionWeight, sample_size) )
但我不确定我是否在正确的轨道上。任何帮助都将不胜感激 我想不出一个聪明的numpythonic方法来实现这一点,它不涉及对数据的多次传递。(有时候numpy比纯Python快得多,这仍然是最快的方式,但感觉永远不对。) 在纯Python中,我会执行以下操作
def draw_unique(vec, n):
# group indices by value
d = {}
for i, x in enumerate(vec):
d.setdefault(x, []).append(i)
drawn = [random.choice(d[k]) for k in random.sample(d, n)]
return drawn
这会给
>>> a = np.random.randint(0, 10, (41000, 3))
>>> drawn = draw_unique(a[:,2], 3)
>>> drawn
[4219, 6745, 25670]
>>> a[drawn]
array([[5, 6, 0],
[8, 8, 1],
[5, 8, 3]])
我能想到一些关于
np.bincount
和scipy.stats.rankdata
的技巧,但它们伤了我的头,最后总是有一步我看不到如何矢量化。。如果我不把整个事情矢量化,我最好使用上面的方法,至少很简单。我相信这会满足你的要求。请注意,运行时间几乎肯定会由生成随机数的任何方法控制。(例外情况是,如果数据集很大,但只需要少量行,在这种情况下,只需要绘制很少的随机数。)因此,我不确定这将比纯python方法运行得快得多
# arrayify your list of lists
# please don't use `array` as a variable name!
a = np.asarray(arry)
# sort the list ... always the first step for efficiency
a2 = a[np.argsort(a[:, 2])]
# identify rows that are duplicates (3rd column is non-increasing)
# Note this has length one less than a2
duplicate_rows = np.diff(a2[:, 2]) == 0)
# if duplicate_rows[N], then we want to remove row N and N+1
keep_mask = np.ones(length(a2), dtype=np.bool) # all True
keep_mask[duplicate_rows] = 0 # remove row N
keep_mask[1:][duplicate_rows] = 0 # remove row N + 1
# now actually slice the array
a3 = a2[keep_mask]
# select rows from a3 using your preferred random number generator
# I actually prefer `random` over numpy.random for sampling w/o replacement
import random
result = a3[random.sample(xrange(len(a3)), DESIRED_NUMBER_OF_ROWS)]
我不知道你说“我想采集唯一值的样本(没有重复项)”是什么意思。您的意思是,如果任何值出现多次,是否要从采样中排除它们?或者您想从所有元素都是唯一的列表中进行采样?或者您希望采样而不替换,因此随机采样的值永远不会重复?还是一些组合?一些示例数据会有所帮助。第三列是否包含从0或1到最大值的所有数字,是否有一些重复的数字,或者序列中是否也有间隙?