'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)
我有以下形式的代码:
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)