У меня есть код вида:
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
Я видел аналогичный вопрос с ответом, но не смог решить проблему Что я делаю не так?
Это выглядит как очень сложный способ вычисления:
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 объясняет проблему. Этот ответ объясняет, почему вам не нужно его исправлять:
Вообще говоря, можно с уверенностью предположить, что если вы когда-нибудь обнаружите, что зацикливаетесь на пустом массиве или кадре данных pandas, вы делаете что-то не так. Эти библиотеки созданы с учетом векторизации и широковещательной передачи, что позволяет выполнять одну и ту же операцию с несколькими данными одновременно.
Если вы когда-нибудь обнаружите, что зацикливаетесь на объекте numpy или pandas, сделайте шаг назад и спросите себя:
Am I calculating a common, standard mathematical function?
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)
Вы были мотивированы ;)
Не знаю, почему я иногда беспокоюсь, лол
Вы назвали возвращаемое значение функции так же, как и сама функция.