Заполните пропущенные значения категориального столбца

avatar
user58653
9 августа 2021 в 02:33
147
1
0

Я пытаюсь заполнить некоторые отсутствующие категориальные значения столбца. У меня 2 колонки. Один категоричен, а другой нет. Если в категориальном столбце отсутствует значение, я хочу присвоить ему значение на основе категориального значения с наибольшим количеством счетчиков.

Мои столбцы выглядят так:

School_Assigned    Will_You_Enroll_There

Anderson           Yes
Williams           No
Anderson           NaN
Anderson           Yes
Anderson           Maybe

Исходя из этого, значение NaN должно содержать Да, так как количество ответов Да (для Андерсона) больше, чем количество ответов Нет и Возможно. School_Assigned и Will_You_Enroll_There — столбцы 10 и 11 соответственно. Мой фрейм данных называется gt_Exam.

Вот мой код:

enroll_categories = ["Yes", "No", "Maybe"]
count1 = 0
count2 = 0
count3 = 0

for i in range(len(gt_Exam)):

    if pd.isna(gt_Exam.iloc[i, 11]) == True:

        value = gt_Exam.iloc[i, 10]

        for j in range(len(gt_Exam)):

            if (gt_Exam.iloc[j, 10] == value) & (gt_Exam.iloc[j, 11] == enroll_categories[0]):

                count1 += 1

            elif (gt_Exam.iloc[j, 10] == value) & (gt_Exam.iloc[j, 11] == enroll_categories[1]):

                count2 += 1

            elif (gt_Exam.iloc[j, 10] == value) & (gt_Exam.iloc[j, 11] == enroll_categories[2]):

                count3 += 1

        maximum_categories = max(count1, count2, count3)

        if maximum_categories == count1:

            gt_Exam.iloc[i, 11] = enroll_categories[0]

        elif maximum_categories == count2:

            gt_Exam.iloc[i, 11] = enroll_categories[1]

        else:

            gt_Exam.iloc[i, 11] = enroll_categories[2]   
Источник

Ответы (1)

avatar
Henry Ecker
9 августа 2021 в 02:41
0

We can try fillna with the first mode per group (groupby transform):

gt_Exam['Will_You_Enroll_There'] = gt_Exam['Will_You_Enroll_There'].fillna(
    gt_Exam.groupby('School_Assigned')['Will_You_Enroll_There']
        .transform(lambda s: pd.Series.mode(s)[0])
)

Series.get можно использовать, если возможно, что группа состоит из всех NaN и, таким образом, не создает режим. Это предотвратит ошибку ключа, а также (необязательно) позволит указать значение по умолчанию:

.
gt_Exam['Will_You_Enroll_There'] = gt_Exam['Will_You_Enroll_There'].fillna(
    gt_Exam.groupby('School_Assigned')['Will_You_Enroll_There']
        .transform(lambda s: pd.Series.mode(s).get(0))
)

gt_Exam:

  School_Assigned Will_You_Enroll_There
0        Anderson                   Yes
1        Williams                    No
2        Anderson                   Yes
3        Anderson                   Yes
4        Anderson                 Maybe

Кадр данных:

import numpy as np
import pandas as pd

gt_Exam = pd.DataFrame({
    'School_Assigned': {0: 'Anderson', 1: 'Williams', 2: 'Anderson',
                        3: 'Anderson', 4: 'Anderson'},
    'Will_You_Enroll_There': {0: 'Yes', 1: 'No', 2: np.nan, 3: 'Yes',
                              4: 'Maybe'}
})
user58653
9 августа 2021 в 02:50
0

По какой-то причине я получаю KeyError: 0

Henry Ecker
9 августа 2021 в 02:55
0

Возможно ли, что у вас есть группы, в которых все NaN?

user58653
9 августа 2021 в 02:56
0

Да, они есть.

Henry Ecker
9 августа 2021 в 02:58
1

Вы можете попробовать get(0) вместо [0], посмотрите на редактирование.

user58653
9 августа 2021 в 03:00
1

Идеальный!! Слаженно работал! Большое спасибо!!

user58653
9 августа 2021 в 03:18
0

Рад найти более чистые способы работы с данными вместо неуклюжих способов в моем стремлении стать Data Scientist!