首页 > 解决方案 > 我收到错误“ValueError:NumPy 布尔数组索引分配无法将 100 个输入值分配给掩码为真的 90 个输出值”

问题描述

这是我的代码,我收到以下错误:

ValueError:NumPy 布尔数组索引分配无法将 100 个输入值分配给掩码为真的 90 个输出值。错误出现在为 V 赋值的行上。

我究竟做错了什么?

from pylab import * 
import numpy as np
from math import *
r = np.linspace(0, 10, 100)

V = np.piecewise(r, [r < 1, r > 1 ], [1, (r/2)*(3 - (r**2))])

#Graph of V r / k q vs. r/R for unitless quantities

figure()
plot(r, V)
xlabel('r / R') 
ylabel('V r / k q') 
title('Behavior of V(r) vs r')

ax = plt.gca()

ax.set_xticks([1])
  
ax.set_xticklabels(['R'])

plt.tick_params(left = False, right = False , labelleft = False)

grid()

show()

标签: pythonnumpy

解决方案


首先你的错误有完整的回溯:

In [1]: r = np.linspace(0, 3, 20)
In [2]: V = np.piecewise(r, [r < 1, r > 1 ], [1, (r/2)*(3 - (r**2))])
Traceback (most recent call last):
  File "<ipython-input-2-0bb13126761c>", line 1, in <module>
    V = np.piecewise(r, [r < 1, r > 1 ], [1, (r/2)*(3 - (r**2))])
  File "<__array_function__ internals>", line 5, in piecewise
  File "/usr/local/lib/python3.8/dist-packages/numpy/lib/function_base.py", line 612, in piecewise
    y[cond] = func
ValueError: NumPy boolean array indexing assignment cannot assign 20 input values to the 13 output values where the mask is true

问题出在piecewise. 如果您(重新)阅读它的文档,您会发现第三个参数列表的元素应该是标量或函数。您提供了一个数组作为第二个。

In [4]: np.size((r/2)*(3 - (r**2)))
Out[4]: 20
In [5]: np.sum(r<1), np.sum(r>1)
Out[5]: (7, 13)

piecewise正在尝试将 7 个值从一个条件分配给数组,将 13 个值分配给另一个。这就是为什么当您为第二个提供全部 20 个时它会抱怨的原因。20 不匹配 13!

如果两个值都是标量:

In [6]: V = np.piecewise(r, [r < 1, r > 1 ], [1, 2])
In [7]: V
Out[7]: 
array([1., 1., 1., 1., 1., 1., 1., 2., 2., 2., 2., 2., 2., 2., 2., 2., 2.,
       2., 2., 2.])

我们可以使用一个 lambda 函数来计算我们想要的 13 个值:

In [8]: V = np.piecewise(r, [r < 1, r > 1 ], [1, lambda i: (i/2)*(3-(i**2))])
In [9]: V
Out[9]: 
array([ 1.        ,  1.        ,  1.        ,  1.        ,  1.        ,
        1.        ,  1.        ,  0.98279633,  0.88700977,  0.6967488 ,
        0.40020411, -0.01443359, -0.55897361, -1.24522525, -2.08499781,
       -3.0901006 , -4.27234291, -5.64353404, -7.21548331, -9.        ])

但我们不需要使用piecewise. 而是评估 的所有值r,并替换选定的值:

In [10]: V = (r/2)*(3 - (r**2))
In [12]: V[r<1] = 1
In [13]: V
Out[13]: 
array([ 1.        ,  1.        ,  1.        ,  1.        ,  1.        ,
        1.        ,  1.        ,  0.98279633,  0.88700977,  0.6967488 ,
        0.40020411, -0.01443359, -0.55897361, -1.24522525, -2.08499781,
       -3.0901006 , -4.27234291, -5.64353404, -7.21548331, -9.        ])

从文档:

funclist : list of callables, f(x,*args,**kw), or scalars
        Each function is evaluated over `x` wherever its corresponding
        condition is True.  It should take a 1d array as input and give an 1d
        array or a scalar value as output.  If, instead of a callable,
        a scalar is provided then a constant function (``lambda x: scalar``) is
        assumed.

所以工作piecewise正在做:

In [17]: fun = lambda i: (i/2)*(3-(i**2))
In [18]: fun(r[r>1])
Out[18]: 
array([ 0.98279633,  0.88700977,  0.6967488 ,  0.40020411, -0.01443359,
       -0.55897361, -1.24522525, -2.08499781, -3.0901006 , -4.27234291,
       -5.64353404, -7.21548331, -9.        ])

创建 13 个值以放入V.


推荐阅读