Я не могу запустить его, но вся ваша проблема в том, что внутри substance_evaluation()
вы используете одно и то же имя substance
для двух переменных, которые должны сохранять разные значения.
Сначала у вас есть substance
in
def substance_evaluation(substance)
, и эта переменная должна содержать "ph"
, но позже вы используете
for ..., substance in ...:
, которые присваивают другое значение этой переменной (вместо "ph"
), а позже вы используете
... >= substance_mean(substance)
для вычисления mean
для "ph"
, но в данный момент substance
не имеет значения "ph"
, а 3.51
( как показать ошибку KeyError: 3.51
)
У вас не было бы этой проблемы, если бы в функции вы сохранили
median = df[substance].mean()
и
if substance >= median:
Помимо использования функции для запуска одна строка кода - пустая трата времени.
И, сохраняя эту линию, вы вычисляете медиану только один раз - до l oop. Используя функцию внутри l oop, вы вычисляете одно и то же значение много раз - и это тоже пустая трата времени.
Я думаю, что в обеих версиях (с функцией и без) у вас все еще могут быть проблемы с substance
, потому что вы также используете его в df.loc[index, substance]
, поэтому он может попытаться сделать df.loc[index, 3.51]
вместо df.loc[index, "ph"]
. Вы должны использовать другое имя ie. value
for ..., value in ...:
if value >= median:
У вас должна быть одна функция вроде этой:
def substance_evaluation(substance):
median = df[substance].mean()
for index, value in enumerate(df[substance]):
if value >= median:
df.loc[index, substance] = 'high'
else:
df.loc[index, substance] = 'low'
print(df.groupby(substance).quality.mean())
Но я думаю, вы могли бы написать ее просто.
def substance_evaluation(substance):
median = df[substance].mean()
mask = (df[substance] >= mediam)
df[substance][ mask ] = 'high'
df[substance][ ~mask ] = 'low'
print(df.groupby(substance).quality.mean())
В итоге с np.where()
def substance_evaluation(substance):
median = df[substance].mean()
mask = (df[substance] >= mediam)
df[substance] = np.where(mask, 'high', 'low')
print(df.groupby(substance).quality.mean())
В этой версии вы можете легко создать новый столбец со значениями
df["new column"] = np.where(mask, 'high', 'low')
РЕДАКТИРОВАТЬ: Минимальный рабочий код для теста
import pandas as pd
import random
import numpy as np
import time
def version1(df, substance):
median = df[substance].mean()
for index, value in enumerate(df[substance]):
if value >= median:
df.loc[index, substance] = 'high'
else:
df.loc[index, substance] = 'low'
def version2(df, substance):
median = df[substance].mean()
mask = (df[substance] >= median)
df[substance][ mask ] = 'high'
df[substance][ ~mask ] = 'low'
def version3(df, substance):
median = df[substance].mean()
mask = (df[substance] >= median)
df[substance] = np.where(mask, 'high', 'low')
# ---
random.seed(0) # to generate always the same values
df = pd.DataFrame({'pH': [random.randint(0,7) for _ in range(5)]})
substance = 'pH'
print('--- before ---')
print(df)
# ---
df1 = df.copy()
start = time.time()
version1(df1, substance)
end = time.time()
print('--- after --- time:', end-start)
print(df1)
# ---
df2 = df.copy()
start = time.time()
version2(df2, substance)
end = time.time()
print('--- after --- time:', end-start)
print(df1)
# ---
df3 = df.copy()
start = time.time()
version3(df3, substance)
end = time.time()
print('--- after --- time:', end-start)
print(df1)