在numpy中执行此操作最明智的方法是什么?

时间:2018-09-18 02:21:35

标签: python numpy

我有一个问题,我想可能会很容易回答。我有一个具有三个维度的numpy数组-(num_users,num_dates,num_holdings)。我想将其初始化为一些随机测试值。 random.rand可以很好地做到这一点,但是对于每个用户和每个日期,第三维必须相加为1(即,对于任何用户和任何日期,其持有量必须相加为1)。我可以通过迭代来做到这一点,如:

num_users = 2
num_dates = 2
num_holdings = 5

test_arr = np.random.rand(num_users, num_dates, num_holdings)

for user in range(num_users):
    for date in range(num_dates):
        starting_total = np.sum(test_arr[user, date, :])
        test_arr[user, date, :] = np.divide(test_arr[user, date, :], starting_total)

# Check it works
print(np.all(np.sum(test_arr, axis=2).reshape(-1)==1))

但是,如果我要创建多个数组,它将开始变得有点慢。另外,感觉还不太令人满意。我想知道是否有人知道使用矢量数学实现这一点的更好方法?

谢谢!

1 个答案:

答案 0 :(得分:0)

您可以

test_arr /= test_arr.sum(axis=2, keepdims=True)

例如:

In [95]: test_arr = np.random.rand(2, 2, 5)

In [96]: test_arr
Out[96]: 
array([[[0.44621493, 0.04093414, 0.30051671, 0.40939041, 0.37251939],
        [0.33997017, 0.81257008, 0.52820553, 0.55382711, 0.11720684]],

       [[0.78460482, 0.43458619, 0.07722273, 0.18181153, 0.52101088],
        [0.47933417, 0.31354249, 0.09966921, 0.59655266, 0.24816989]]])

In [97]: test_arr.sum(axis=2, keepdims=True)
Out[97]: 
array([[[1.56957558],
        [2.35177973]],

       [[1.99923614],
        [1.73726842]]])

使用keepdims=True意味着我们得到的结果形状(2,2,1)在除以它后将正确广播。

In [98]: test_arr /= test_arr.sum(axis=2, keepdims=True)

In [99]: test_arr.sum(axis=2)
Out[99]: 
array([[1., 1.],
       [1., 1.]])

请注意,由于精度有限,您不能得到精确的 1.0,但差异可以忽略不计:

In [100]: test_arr.sum(axis=2) - 1.0
Out[100]: 
array([[ 0.00000000e+00,  0.00000000e+00],
       [-1.11022302e-16, -1.11022302e-16]])