Numpy: 给定标量条件列表的1-D数组np.select
我想实现这样的功能:
def choozer(my_1D_array):
newArray = np.zeros((len(my_1D_array), 5))
for x in enumerate(my_1D_array):
if x[1]<3:
y = np.array([1,1,1,1,1]) #the y's can be any array of random values
elif 3<=x[1]<=5:
y = np.array([2,2,2,2,2])# don't need to be repeated
elif x[1]>5:
y = np.array([3,3,3,3,3])
newArray[x[0]] = y
return newArray
这个方法有效……但对我来说感觉有点绕,而且在我的应用中效率很重要。所以我想到可以用np.select来做个比较:
def np_choozer(my_1D_array):
condlist = [my_1D_array<3,
np.logical_and((3<=my_1D_array),(my_1D_array<=5)),
my_1D_array>5]
choicelist = [np.array([1,1,1,1,1]),
np.array([2,2,2,2,2]),
np.array([3,3,3,3,3])]
return np.select(condlist, choicelist)
……但没有成功。它在轴1上返回了选择列表的值。有没有更好的方法来解决我上面提到的问题呢?
提前谢谢你。
3 个回答
0
这个,
import numpy as np
a = np.arange(10)
one = np.ones((5,a.shape[0]))
two = 2 * one
thr = 3 * one
def choozer(a):
condlist = [a<3, np.logical_and((3<=a),(a<=5)), a>5]
choicelist = [one,two,thr]
return np.select(condlist, choicelist).T
print choozer(a)
会得到这个,
[[ 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1.]
[ 1. 1. 1. 1. 1.]
[ 2. 2. 2. 2. 2.]
[ 2. 2. 2. 2. 2.]
[ 2. 2. 2. 2. 2.]
[ 3. 3. 3. 3. 3.]
[ 3. 3. 3. 3. 3.]
[ 3. 3. 3. 3. 3.]
[ 3. 3. 3. 3. 3.]]
1
也许可以用 np.select
写得更好,但你总是可以这样做:
newArray = np.zeros(my_1D_array.shape + (5,))
newArray[np.where(my_1D_array < 3)] = 1
newArray[np.where((my_1D_array >= 3) & (my_1D_array <= 5)] = 2
newArray[np.where(my_1D_array > 5)] = 3
这是一个例子:
>>> a = np.random.rand(10) * 10
>>> b = np.empty(a.shape + (5,))
>>> b[np.where(a < 3)] = 1
>>> b[np.where((a >= 3) & (a <= 5))] = 2
>>> b[np.where(a > 5)] = 3
>>> b
array([[ 1., 1., 1., 1., 1.],
[ 3., 3., 3., 3., 3.],
[ 2., 2., 2., 2., 2.],
[ 3., 3., 3., 3., 3.],
[ 1., 1., 1., 1., 1.],
[ 3., 3., 3., 3., 3.],
[ 3., 3., 3., 3., 3.],
[ 3., 3., 3., 3., 3.],
[ 1., 1., 1., 1., 1.],
[ 3., 3., 3., 3., 3.]])
编辑 上面的代码利用了赋值中的广播功能,不过 1
、2
和 3
可以用一个包含5个元素的列表或数组来替代。使用和上面例子相同的 a
和 b
:
>>> b[np.where(a < 3)] = np.arange(5)
>>> b[np.where((a >= 3) & (a <= 5))] = np.arange(5) + 10
>>> b[np.where(a > 5)] = np.arange(5) + 20
>>> b
array([[ 0., 1., 2., 3., 4.],
[ 20., 21., 22., 23., 24.],
[ 10., 11., 12., 13., 14.],
[ 20., 21., 22., 23., 24.],
[ 0., 1., 2., 3., 4.],
[ 20., 21., 22., 23., 24.],
[ 20., 21., 22., 23., 24.],
[ 20., 21., 22., 23., 24.],
[ 0., 1., 2., 3., 4.],
[ 20., 21., 22., 23., 24.]])
0
np_choozer
对 my_1D_array.reshape(-1,1)
的结果是正确的。谢谢你们的帮助……不过我还是想看看有没有其他人能想出更好的方法。