Условное соотношение с группой в пандах - PullRequest
0 голосов
/ 01 октября 2018

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

Пример приведен ниже:

d = {'col1': [1, 2, 1, 2], 'col2': [3, 4, 2, 7], 'col3': [1, 1, 0, 0]}
df = pd.DataFrame(data=d)

    col1    col2    col3
0   1       3       1
1   2       4       1
2   1       2       0
3   2       7       0

Я хочу создать новый столбец: col4.Для этого столбца я группирую по col1, а затем получаю процент значений col2, где col3 равно 1, деленное на общую сгруппированную сумму col2.Так что я бы в итоге получил следующий результат.(Я делю его на дроби, чтобы было легче следить за вычислениями.

    col1    col2    col3    col4
0   1       3       1       3/5
1   2       4       1       4/11
2   1       2       0       3/5
3   2       7       0       4/11

Я пробовал следующее, но, к сожалению, это не работает:

df.col4 = df.groupby(['col1']).transform(lambda x: np.where(x.col3 == 1, x.col2, 0).sum()) / df.groupby(['col1']).col2.transform('sum')

Редактировать |Расширенный пример

Я расширил пример, поскольку решение, предоставленное Веном, охватывало только приведенный выше простой пример.

d = {'col1': [1, 2, 1, 2, 1, 2], 'col2': [3, 4, 2, 7, 6, 8], 'col3': [1, 1, 0, 0, 1, 0]}
df = pd.DataFrame(data=d)
    col1    col2    col3
0   1       3       1
1   2       4       1
2   1       2       0
3   2       7       0
4   1       6       1
5   2       8       0

Редактировать | Возможное решение

Я нашел возможное решение. Я хотел бы сделать это более понятным способом, но это читабельно и довольно просто. Любые альтернативы для объединения этих двух строк кода по-прежнему приветствуются.

df['col4'] = np.where(df.col3 == 1, df.col2, 0)
df['col4'] = df.groupby(['col1']).col4.transform('sum') / df.groupby(['col1']).col2.transform('sum')

Ответы [ 2 ]

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

просто:)

d = {'col1': [1, 2, 1, 2], 'col2': [3, 4, 2, 7], 'col3': [1, 1, 0, 0]}
df = pd.DataFrame(data=d)

df['col4'] = 0.0

def con(data):
    part_a = sum(data[data['col3'] == 1]['col2'])
    part_b = sum(data['col2'])
    data.col4 = part_a/part_b
    return data

df.groupby('col1').apply(con)

Вывод

  col1 col2 col3 col4
0  1    3    1    0.600000 
1  2    4    1    0.363636 
2  1    2    0    0.600000 
3  2    7    0    0.363636 
0 голосов
/ 01 октября 2018

Вам может потребоваться исправить ожидаемый результат, затем использовать map после фильтра

df.col1.map(df.loc[df.col3==1,].set_index('col1').col2)/df.groupby(['col1']).col2.transform('sum')
Out[566]: 
0    0.600000
1    0.363636
2    0.600000
3    0.363636
dtype: float64
...