#python #pandas #performance
Вопрос:
Давайте возьмем этот образец фрейма данных и этот список идентификаторов :
df=pd.DataFrame({'Id':['A','A','A','B','C','C','D','D'], 'Weight':[50,20,30,1,2,8,3,2], 'Value':[100,100,100,10,20,20,30,30]})
Id Weight Value
0 A 50 100
1 A 20 100
2 A 30 100
3 B 1 10
4 C 2 20
5 C 8 20
6 D 3 30
7 D 2 30
L = ['A','C']
Столбец Значение имеет одинаковые значения для каждого идентификатора в столбце Идентификатор. Для конкретных идентификаторов L я хотел бы применить вес столбца » Вес «к столбцу «Значение». В настоящее время я делаю следующее, но это очень медленно с моим реальным большим фреймом данных :
for i in L :
df.loc[df["Id"]==i,"Value"] = (df.loc[df["Id"]==i,"Value"] * df.loc[df["Id"]==i,"Weight"] /
df[df["Id"]==i]["Weight"].sum())
Как, пожалуйста, я мог бы сделать это эффективно ?
Ожидаемый результат :
Id Weight Value
0 A 50 50
1 A 20 20
2 A 30 30
3 B 1 10
4 C 2 4
5 C 8 16
6 D 3 30
7 D 2 30
Ответ №1:
Идея работает только для отфильтрованных строк по Series.isin
с GroupBy.transform
и sum
для суммы по группам с тем же размером, что и исходный кадр данных:
L = ['A','C']
m = df['Id'].isin(L)
df1 = df[m].copy()
s = df1.groupby('Id')['Weight'].transform('sum')
df.loc[m, 'Value'] = df1['Value'].mul(df1['Weight']).div(s)
print (df)
Id Weight Value
0 A 50 50.0
1 A 20 20.0
2 A 30 30.0
3 B 1 10.0
4 C 2 4.0
5 C 8 16.0
6 D 3 30.0
7 D 2 30.0