У меня есть столбец Class
, который может быть 1, 2 или 3, и еще один столбец Age
с некоторыми недостающими данными. Я хочу вменять средний Age
каждой группы Class
.
Я хочу что-то сделать вместе:
grouped_data = df.groupBy('Class')
imputer = Imputer(inputCols=['Age'], outputCols=['imputed_Age'])
imputer.fit(grouped_data)
Есть ли способ обхода этого?
Спасибо за ваше время
Вам необходимо преобразовать фрейм данных с помощью подобранной модели. Затем возьмите среднее значение заполненных данных:
from pyspark.sql import functions as F
imputer = Imputer(inputCols=['Age'], outputCols=['imputed_Age'])
imp_model = imputer.fit(df)
transformed_df = imp_model.transform(df)
transformed_df \
.groupBy('Class') \
.agg(F.avg('Age'))
Используя Imputer, вы можете отфильтровать набор данных по каждому значению Class
, вычислить среднее значение, а затем снова объединить их, поскольку вы заранее знаете, какими могут быть значения:
subsets = []
for i in range(1, 4):
imputer = Imputer(inputCols=['Age'], outputCols=['imputed_Age'])
subset_df = df.filter(col('Class') == i)
imputed_subset = imputer.fit(subset_df).transform(subset_df)
subsets.append(imputed_subset)
# Union them together
# If you only have 3 just do it without a loop
imputed_df = subsets[0].unionByName(subsets[1]).unionByName(subsets[2])
Если вы не знаете заранее, каковы значения, или если их сложно итерировать, вы можете groupBy, получить средние значения для каждой группы в виде DataFrame, а затем объединить их обратно в исходный фрейм данных.
import pyspark.sql.functions as F
averages = df.groupBy("Class").agg(F.avg("Age").alias("avgAge"))
df_with_avgs = df.join(averages, on = "Class")
imputed_df = df_with_avgs.withColumn("imputedAge", F.coalesce("Age", "avgAge"))
Спасибо за Ваш ответ. Кстати, это не совсем то, что я хотел. Мне нужно вменять среднее значение возраста, когда класс == 1 в отсутствующих значениях возраста, когда класс == 1, среднее значение возраста, когда класс == 2 в отсутствующих значениях возраста, когда класс == 2, и то же самое, когда Class == 3.