Создайте переменную общего ресурса после объединенной группировки в панде - PullRequest
0 голосов
/ 15 октября 2018

У меня возникли проблемы с описанием моей проблемы, поэтому я сразу же приступлю к ней.Вот некоторые тестовые данные:

import pandas as pd
df = pd.DataFrame(data={"family":["Smith","Miller","Simpson","Miller","Simpson","Smith","Miller","Simpson","Miller"],
                    "first_name":["Anna","Bart","Lisa","Ida","Paul","Bridget","Harry","Dustin","George"],
                    "shirt_color":["green","yellow","red","yellow","green","red","yellow","red","red"]})

Теперь я хотел бы создать новый столбец в моем исходном фрейме данных, который будет содержать долю рубашки_цвета на семью, поэтому в каждой строке, например, семейство Миллер и рубашка желтая, естьто же значение 0,75 и т. д.

Я пробовал несколько подходов, но ни с одним из них не получилось.

df = df.groupby("family").apply(lambda x: x.groupby("shirt_color").apply(lambda x: x.size()/familysize))

Это казалось многообещающим, но, как вы можете видеть, я не смогполучить доступ к количеству членов семьи в последней лямбда-функции больше.Я также пытался создать объект groupby только из семейства и выполнять итерацию по фреймам данных, группируя все фреймы данных по цветам по отдельности, но каким-то образом мне не удалось в конце вернуть фреймы данных обратно к одному.

Это не 'Похоже, что это очень экзотическая вещь, связанная с фреймом данных, поэтому я уверен, что есть простой способ сделать это, но у меня нет идей.

Большое спасибо за вашу помощь заранее!

Ответы [ 4 ]

0 голосов
/ 15 октября 2018

Использование value_counts и merge:

s = (df.groupby('family').shirt_color
        .value_counts(normalize=True).rename('ratio').reset_index())

    family shirt_color     ratio
0   Miller      yellow  0.750000
1   Miller         red  0.250000
2  Simpson         red  0.666667
3  Simpson       green  0.333333
4    Smith       green  0.500000
5    Smith         red  0.500000

Чтобы поместить это обратно в исходный фрейм данных:

df.merge(s)

    family first_name shirt_color     ratio
0    Smith       Anna       green  0.500000
1   Miller       Bart      yellow  0.750000
2   Miller        Ida      yellow  0.750000
3   Miller      Harry      yellow  0.750000
4  Simpson       Lisa         red  0.666667
5  Simpson     Dustin         red  0.666667
6  Simpson       Paul       green  0.333333
7    Smith    Bridget         red  0.500000
8   Miller     George         red  0.250000
0 голосов
/ 15 октября 2018

На мой взгляд, вам следует избегать apply, так как это приводит к неэффективному циклу уровня Python.Вот альтернативное решение с использованием GroupBy + transform:

f = df.groupby('family')['first_name'].transform('size')
g = df.groupby(['family', 'shirt_color'])['first_name'].transform('size')

df['ratio'] = g / f

print(df)

    family first_name shirt_color     ratio
0    Smith       Anna       green  0.500000
1   Miller       Bart      yellow  0.750000
2  Simpson       Lisa         red  0.666667
3   Miller        Ida      yellow  0.750000
4  Simpson       Paul       green  0.333333
5    Smith    Bridget         red  0.500000
6   Miller      Harry      yellow  0.750000
7  Simpson     Dustin         red  0.666667
8   Miller     George         red  0.250000
0 голосов
/ 15 октября 2018

Попробуйте:

df.groupby('family').apply(lambda g: g.groupby("shirt_color").apply(lambda x: x.size/g.size)).reset_index()
0 голосов
/ 15 октября 2018

Ты почти у цели.Просто используйте разные имена переменных.Используя x, вы переопределяете предыдущую переменную и не можете получить к ней доступ

df.groupby("family").apply(lambda s: s.groupby("shirt_color").apply(lambda x: x.size/s.size))

family   shirt_color
Miller   red            0.250000
         yellow         0.750000
Simpson  green          0.333333
         red            0.666667
Smith    green          0.500000
         red            0.500000
dtype: float64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...