类型错误:只有长度为 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 18:13:09  来源:igfitidea点击:

TypeError: only length-1 arrays can be converted to Python scalars while plot showing

pythonnumpy

提问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.vectorizeis 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 FFT

Use:

用:

x.astype(int)

Here is the reference.

这是参考

回答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-1would 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 vectorizeis 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