我偶然发现了一个小问题,试图使用numpy在人群中创建随机选择的样本矩阵。
我要创建的是一个矩阵,每行代表我的总体样本,这样我就可以一次更高效地对每个样本进行操作。
我尝试执行以下操作:
import numpy as np
l = ["L"] * 36 + ["T1"]*20 + [0]*43
pop = np.array(l)
ech = np.random.choice(a = pop, size=7, replace=False) # This is what I want my sample to be
A = np.full((30,1),7) # Here I want 30 samples in my matrix
np.apply_along_axis(arr=A, func1d=np.random.choice, axis=1, a = pop)
但是,出现以下错误:
TypeError: choice() got multiple values for keyword argument 'a'
由于np.random.choice
函数带有多个参数,因此我创建了一个用7填充的矩阵A(因为我希望从pop中获得7个元素的样本),以便size参数来自A的每一行的值,并且一个参数由a=pop
结尾。
我想知道是否有人知道这里的错误以及如何解决它。
我用过的np.apply_along_axis
来创建这个样本矩阵,因为我会用R中的apply
函数以类似的方式来完成,但是也许有更好的方法吗?
答案 0 :(得分:1)
您尝试使用apply_along_axis
令人困惑,但是我认为您正在尝试这样做:
pop
中的一个样本集:
In [110]: pop = list('abcdefgijklm')
In [111]: np.random.choice(pop, size=7, replace=False)
Out[111]: array(['g', 'm', 'f', 'l', 'c', 'i', 'k'], dtype='<U1')
作为以size
作为参数的函数进行广播:
In [112]: f = lambda s: np.random.choice(pop, size=s, replace=False)
直接进行Python迭代,生成大小不同的样本:
In [113]: [f(i) for i in [3,5,4]]
Out[113]:
[array(['j', 'b', 'l'], dtype='<U1'),
array(['l', 'e', 'k', 'm', 'b'], dtype='<U1'),
array(['k', 'm', 'j', 'b'], dtype='<U1')]
但是要制作示例数组,size
必须相同,所以我们可以这样做:
In [114]: np.array([f(7) for _ in range(3)])
Out[114]:
array([['a', 'f', 'm', 'd', 'e', 'l', 'j'],
['i', 'g', 'f', 'b', 'j', 'e', 'l'],
['j', 'm', 'k', 'i', 'l', 'a', 'b']], dtype='<U1')
但是由于您坚持使用apply_along_axis
,因此可以采用以下方法:
In [122]: A = np.full((5,1), 7)
In [123]: np.apply_along_axis(f, 1, A)
Out[123]:
array([['c', 'm', 'a', 'f', 'i', 'd', 'k'],
['j', 'm', 'k', 'd', 'b', 'l', 'g'],
['b', 'f', 'i', 'm', 'c', 'l', 'k'],
['k', 'f', 'd', 'l', 'b', 'c', 'g'],
['l', 'f', 'j', 'k', 'g', 'a', 'd']], dtype='<U1')
它将np.array([7])
传递到f
5次,并将结果收集到一个数组中。在时间上,此apply
版本比我的[113]
迭代要慢一些。
要传递pop
作为参数,我们必须定义一个func1d
,例如:
In [135]: f = lambda s, a: np.random.choice(a, s, replace=False)
In [136]: np.apply_along_axis(f, 1, A, a=pop)
Out[136]:
array([['j', 'd', 'b', 'f', 'c', 'l', 'k'],
['d', 'c', 'e', 'j', 'm', 'k', 'i'],
['l', 'g', 'j', 'k', 'e', 'f', 'a'],
['a', 'l', 'e', 'm', 'b', 'c', 'j'],
['j', 'e', 'g', 'f', 'l', 'd', 'a']], dtype='<U1')
当apply_along_axis
为3d(或更大)时, A
很有用,并且您想将一个功能应用于一个轴,然后在另一个轴上进行迭代。比以下方法更容易应用:
for i in range...:
for j in range ...:
res[i,j,:] = func1d(A[i,j,:])
但是您构造了一个2d数组(n,1),只是可以在第一个轴上进行迭代,将第二个(大小为1)的轴传递给该函数。在(n,)数组上进行迭代在概念上和计算上都更简单。