Дан следующий набор данных df
:
type module item value input
0 A a item1 2 1
1 A a item2 3 0
2 A aa item3 4 1
3 A aa item4 3 0
4 A aa item5 1 -1
5 B b item1 5 0
6 B b item2 1 -1
7 B bb item3 3 0
8 B bb item4 3 1
9 B bb item5 4 0
Мне нужно вычислить sum
из pct
на основе следующей логики: сначала мы берем только value
, input
которого равно 0
или 1
как допустимые значения. Затем мне нужно сгруппировать по type, module
, чтобы вычислить процент от суммы, например, pct
первой строки A-a-item1
вычисляется по 2/(2 + 3) = 0.4
, A-aa-item1
вычисляется на 4/(4 + 3) = 0.57
, а не на 8
, поскольку входное значение для A-aa-item3
равно -1
, поэтому оно исключается. Столбец sum
в df2
рассчитывается по группам type module
, а затем по сумме sum
.
df1:
type module item value input pct
0 A a item1 2 1 0.400000
1 A a item2 3 0 0.000000
2 A aa item1 4 1 0.571429
3 A aa item2 3 0 0.000000
4 A aa item3 1 -1 0.000000
5 B b item1 5 0 0.000000
6 B b item2 1 -1 0.000000
7 B bb item1 3 0 0.000000
8 B bb item2 3 1 0.300000
9 B bb item3 4 0 0.000000
df2:
type module sum
0 A a 0.40
1 A aa 0.57
2 B b 0.00
3 B bb 0.30
Как я могу получить аналогичные результаты на основе данного набора данных? Спасибо.
1 ответ
Вы можете заменить несоответствие условиям на Series.eq
для сравнения по 1
с 0
и сравнения по 0, 1
по Series.isin
, вместо этого используется агрегирование GroupBy.transform
с sum
для нового столбца, заполненного агрегированными значениями и разделены на Series.div
а>:
s1 = df['value'].where(df['input'].eq(1), 0)
s2 = (df.assign(value = df['value'].where(df['input'].isin([0,1]), 0))
.groupby(['type','module'])['value'].transform('sum'))
df['pct '] = s1.div(s2)
print (df)
type module item value input pct
0 A a item1 2 1 0.400000
1 A a item2 3 0 0.000000
2 A aa item3 4 1 0.571429
3 A aa item4 3 0 0.000000
4 A aa item5 1 -1 0.000000
5 B b item1 5 0 0.000000
6 B b item2 1 -1 0.000000
7 B bb item3 3 0 0.000000
8 B bb item4 3 1 0.300000
9 B bb item5 4 0 0.000000
Для второго DataFrame
добавлены 2 новых столбца с помощью DataFrame.assign
, агрегировать sum
и последнее деление с помощью DataFrame.pop
для использования и удаления столбца value
:
df2 = (df.assign(value = df['value'].where(df['input'].isin([0,1]), 0),
pct = df['value'].where(df['input'].eq(1), 0))
.groupby(['type','module'])[['value','pct']]
.sum()
.assign(pct = lambda x: x['pct'].div(x.pop('value')))
.reset_index())
print (df2)
type module pct
0 A a 0.400000
1 A aa 0.571429
2 B b 0.000000
3 B bb 0.300000
pct
для df
, нам нужно исключить значения input=-1
из сумм.
pct = df['value'].where(df['input'].eq(1), 0)
на pct = df['value'].where(df['input'] != -1, 0)
?
value
на другое имя, но в каком-то коде оно сохраняется.
Похожие вопросы
Связанные вопросы
Новые вопросы
python-3.x
НЕ ИСПОЛЬЗУЙТЕ, ЕСЛИ ВАШ ВОПРОС ТОЛЬКО ДЛЯ PYTHON 3. Всегда используйте вместе со стандартным тегом [python].
0
или1
, а затем сравнить на1
, поэтому строки с-1, 0
устанавливаются в0
вpct
?