Home > OS >  Weighted average of a dictionary - Pandas
Weighted average of a dictionary - Pandas

Time:01-21

I have the following column in a data-frame (it is an example):

First row is: '{"100":10,"50":3,"-90":2}'.

Second row is: '{"100":70,"50":3,"-90":2,"-40":3}'.

I want to calculate a weighted average where the dictionary's keys are the values and the dictionary's values are the weights of the weighted average.

The final value of the first row should be: 64.666, which is (100*10 50*3-90*2)/(10 3 2); and the of the second row should be: 87.82.

For each dictionary there might be hundreds of keys/values and the column might have thousands of rows. How can I code it efficiently? Preferably vectorially.

CodePudding user response:

You can use json.loads and pandas.Series.apply.

import json

def cal_avg(dct):
    dct = json.loads(dct)
    return sum(int(k)*v for k,v in dct.items()) / sum(dct[k] for k in dct)

df['dct'].apply(cal_avg)

Output:

0    64.666667
1    87.820513
Name: dct, dtype: float64

Input DataFrame:

import pandas as pd
df = pd.DataFrame({
    'dct': [
        '{"100":10,"50":3,"-90":2}',
        '{"100":70,"50":3,"-90":2,"-40":3}'
    ]
})

CodePudding user response:

Your first row is missing a column, so I'm assuming there's a NaN value there.

Edit: whoops, mixed up my values and weights

df = pd.DataFrame({'100': [10, 70], '50': [3, 3], '-90': [2, 2,], '-40': [None, 3]})

get_values = df.columns.values.astype('int')

df['weighted_avg'] = np.nansum(get_values*df.values, axis = 1) / np.nansum(df.values, axis = 1)

CodePudding user response:

try this easy for loop:

dataset = [{"100": 10, "50": 3, "-90": 2}, {"100": 70, "50": 3, "-90": 2, "-40": 3}]

for data in dataset:
    weighted_value = 0
    weight = 0
    for item in data.items():
        weighted_value  = int(item[0]) * item[1]
        weight  = item[1]
    weighted_average = weighted_value / weight
    print(weighted_average)

performance wise i dont think this can be optimized a lot further.

  • Related