【问题标题】:TypeError: only length-1 arrays can be converted to Python scalars while plot showingTypeError:只有长度为 1 的数组可以转换为 Python 标量,同时显示绘图
【发布时间】:2016-08-09 09:20:58
【问题描述】:

我有这样的 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()

还有这样的错误:

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

我该如何解决?

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    当函数需要单个值但您传递一个数组时,会引发错误“只有长度为 1 的数组可以转换为 Python 标量”。

    如果您查看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()
    

    您可以跳过 f(x) 的定义,只需将 np.int 传递给 vectorize 函数:f2 = np.vectorize(np.int)

    请注意,np.vectorize 只是一个便利函数,基本上是一个 for 循环。这在大型阵列上效率低下。只要有可能,请使用真正矢量化的函数或方法(例如 astype(int)@FFT suggests)。

    【讨论】:

    • 更干净,我想也更快(我应该测试)。对于这样的事情,我仍然需要学习 numpy 的复杂性:)
    • 有趣的是,我的答案似乎更快,并且我给出了调查背后的原因,但我不知道性能差异的真正原因。也许有人会有所启发:)
    • np.int 只是拼写int 的一种令人困惑的方式。永远不要使用前者。您的代码可以简化为f = int
    • @ayhan: 如果我想将 numpy array 转换为 object ,我可以将其插入到 MongoDB 中怎么办? /跨度>
    • np.int() 已弃用。
    【解决方案2】:

    用途:

    x.astype(int)
    

    这里是reference

    【讨论】:

    • 与接受的答案相比,此答案有效,不推荐使用 np.int()。
    【解决方案3】:

    dataframe['column'].squeeze() 应该可以解决这个问题。它基本上将数据框列更改为列表。

    【讨论】:

      【解决方案4】:

      注意为x 打印的内容。您正在尝试将数组(基本上只是一个列表)转换为 int。 length-1 将是单个数字的数组,我假设 numpy 只是将其视为浮点数。你可以这样做,但这不是一个纯粹的 numpy 解决方案。

      编辑:几周前我参与了一篇帖子,其中 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
      

      【讨论】:

        【解决方案5】:

        在这种情况下,输出必须是一个四舍五入的int 值。

        import numpy as np
        
        arr = np.array([2.34, 2.56, 3.12])
        output = np.round(arr).astype(int)
        
        print(output)
        # array([2, 3, 3])
        

        【讨论】:

          猜你喜欢
          • 2014-09-27
          • 2013-03-15
          • 1970-01-01
          • 2016-08-06
          • 2018-09-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多