'numpy.float64' 对象不能用 numpy 调用,pandas 不能用自定义函数调用

'numpy.float64' object is not callable with numpy and pandas with custom function

我有以下形式的代码:

import pandas as pd
import numpy as np

def StrdErr(vec):
  return np.std(vec)/np.sqrt(len(vec))

df2 = pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]), columns=['a', 'b', 'c'])

for idx_q in range(0, df2.shape[0]):
  StrdErr = StrdErr(np.array(df2.loc[idx_q, :]))

出现以下错误消息:

Traceback (most recent call last):
  File "debug.py", line 11, in <module>
    StrdErr = StrdErr(np.array(df2.loc[idx_q, :]))
TypeError: 'numpy.float64' object is not callable

我看到一个similar question with answer但是没能解决问题 我做错了什么?

这看起来是一种非常复杂的计算方式:

df2.std(1, ddof=0).div(np.sqrt(df2.shape[1]))

输出:

0    0.471405
1    0.471405
2    0.471405
dtype: float64
即使效率低下,要修复循环,请使用:
out = []
for idx_q in range(0, df2.shape[0]):
  out.append(StrdErr(np.array(df2.loc[idx_q, :])))
print(out)
# [0.47140452079103173, 0.47140452079103173, 0.47140452079103173]

DavidG 的评论解释了这个问题。这个答案解释了为什么你不需要费心去修复它:

一般来说,如果您发现自己在 numpy 数组或 pandas 数据帧上循环,则可以安全地假设您做错了什么。这些库在构建时考虑了矢量化和广播——允许您同时对多个数据执行相同的操作。

如果您发现自己在循环使用 numpy 或 pandas 对象,请退一步问问自己:

Am I calculating a common, standard mathematical function?

  • 如果是这样,请尝试在包的文档中搜索它——很可能它已经足够普遍以实现(例如,标准差、相关系数等)
  • 如果不是,请尝试从 vector-math 的角度解决问题——如果您在 for 循环中计算的是数组或数据帧的单个元素上的标量方程一次,然后您可以将方程向量化以一次对整个向量执行该操作

在这种情况下,平均值的标准误差是一个常见的数学函数,Pandas 在其库中作为 pandas.DataFrame.sem:

df.sem(ddof=0, axis=1)

看看 (1000, 3) 数据帧的性能差异:

In [3]: def StrdErr(df):
   ...:     out = []
   ...:     for idx_q in range(0, df.shape[0]):
   ...:         vec = np.array(df.loc[idx_q, :])
   ...:         out.append(np.std(vec) / np.sqrt(len(vec)))
   ...:     return out

In [4]: df.shape
Out[4]: (1000, 3)

In [5]: %timeit StrdErr(df)
118 ms ± 10.4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [6]: %timeit df.sem(ddof=0, axis=1)
453 µs ± 56.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)