类型错误:只有长度为 1 的数组可以在绘图显示时转换为 Python 标量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36680402/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TypeError: only length-1 arrays can be converted to Python scalars while plot showing
提问by K. Kovalev
I have such Python code:
我有这样的 Python 代码:
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return np.int(x)
x = np.arange(1, 15.1, 0.1)
plt.plot(x, f(x))
plt.show()
And such error:
还有这样的错误:
TypeError: only length-1 arrays can be converted to Python scalars
How can I fix it?
我该如何解决?
回答by ayhan
The error "only length-1 arrays can be converted to Python scalars" is raised when the function expects a single value but you pass an array instead.
当函数需要单个值但您传递一个数组时,会引发错误“仅长度为 1 的数组可以转换为 Python 标量”。
If you look at the call signature of np.int
, you'll see that it accepts a single value, not an array. In general, if you want to apply a function that accepts a single element to every element in an array, you can use np.vectorize
:
如果查看 的调用签名np.int
,您会发现它接受单个值,而不是数组。通常,如果要将接受单个元素的函数应用于数组中的每个元素,可以使用np.vectorize
:
import numpy as np
import matplotlib.pyplot as plt
def f(x):
return np.int(x)
f2 = np.vectorize(f)
x = np.arange(1, 15.1, 0.1)
plt.plot(x, f2(x))
plt.show()
You can skip the definition of f(x) and just pass np.int to the vectorize function: f2 = np.vectorize(np.int)
.
您可以跳过F(X)的定义,只是通过np.int到矢量化功能:f2 = np.vectorize(np.int)
。
Note that np.vectorize
is just a convenience function and basically a for loop. That will be inefficient over large arrays. Whenever you have the possibility, use truly vectorized functions or methods (like astype(int)
as @FFT suggests).
请注意,这np.vectorize
只是一个方便的函数,基本上是一个 for 循环。这在大型阵列上效率低下。每当你有可能,使用真正的矢量函数或方法(如astype(int)
为@FFT建议)。
回答by roganjosh
Take note of what is printed for x
. You are trying to convert an array (basically just a list) into an int. length-1
would be an array of a single number, which I assume numpy just treats as a float. You could do this, but it's not a purely-numpy solution.
注意打印的内容x
。您正在尝试将数组(基本上只是一个列表)转换为 int。length-1
将是单个数字的数组,我认为 numpy 只是将其视为浮点数。你可以这样做,但这不是一个纯粹的 numpy 解决方案。
EDIT: I was involved in a post a couple of weeks back where numpy was slower an operation than I had expected and I realised I had fallen into a default mindset that numpy was always the way to go for speed. Since my answer was not as clean as ayhan's, I thought I'd use this space to show that this is another such instance to illustrate that vectorize
is around 10% slower than building a list in Python. I don't know enough about numpy to explain why this is the case but perhaps someone else does?
编辑:几周前我参与了一个帖子,其中 numpy 的操作比我预期的要慢,我意识到我已经陷入了一种默认的心态,即 numpy 总是追求速度的方式。由于我的回答不像 ayhan 的那么清晰,我想我会用这个空间来表明这是另一个这样的例子来说明它vectorize
比在 Python 中构建列表慢 10% 左右。我对 numpy 的了解不够,无法解释为什么会这样,但也许其他人会这样做?
import numpy as np
import matplotlib.pyplot as plt
import datetime
time_start = datetime.datetime.now()
# My original answer
def f(x):
rebuilt_to_plot = []
for num in x:
rebuilt_to_plot.append(np.int(num))
return rebuilt_to_plot
for t in range(10000):
x = np.arange(1, 15.1, 0.1)
plt.plot(x, f(x))
time_end = datetime.datetime.now()
# Answer by ayhan
def f_1(x):
return np.int(x)
for t in range(10000):
f2 = np.vectorize(f_1)
x = np.arange(1, 15.1, 0.1)
plt.plot(x, f2(x))
time_end_2 = datetime.datetime.now()
print time_end - time_start
print time_end_2 - time_end