Pandas Multiply Dictionary Values ​​by Multiple Columns

For the next data frame:

import pandas as pd df = pd.DataFrame({ 'a': [1,2,3,4,5], 'b': [5,4,3,3,4], 'c': [3,2,4,3,10], 'd': [3, 2, 1, 1, 1] }) 

And the following list of options:

 params = {'a': 2.5, 'b': 3.0, 'c': 1.3, 'd': 0.9} 

Produce the following desired conclusion:

  abcd output 0 1 5 3 3 24.1 1 2 4 2 2 21.4 2 3 3 4 1 22.6 3 4 3 3 1 23.8 4 5 4 10 1 38.4 

I used this to get the result:

 df['output'] = [np.sum(params[col] * df.loc[idx, col] for col in df) for idx in df.index] 

However, this is a very slow approach, and I think there should be a better way to use the pandas built-in functionality.

I also thought about this:

 # Line up the parameters col_sort_key = list(df) params_sorted = sorted(params.items(), key=lambda k: col_sort_key.index(k[0])) # Repeat the parameters *n* number of times values = [v for k, v in params_sorted] values = np.array([values] * df.shape[0]) values array([[ 2.5, 3. , 1.3, 0.9], [ 2.5, 3. , 1.3, 0.9], [ 2.5, 3. , 1.3, 0.9], [ 2.5, 3. , 1.3, 0.9], [ 2.5, 3. , 1.3, 0.9]]) # Multiply and add product = df[col_sort_key].values * values product array([[ 2.5, 15. , 3.9, 2.7], [ 5. , 12. , 2.6, 1.8], [ 7.5, 9. , 5.2, 0.9], [ 10. , 9. , 3.9, 0.9], [ 12.5, 12. , 13. , 0.9]]) np.sum(product, axis=1) array([ 24.1, 21.4, 22.6, 23.8, 38.4]) 

But that seems a bit confusing! Any thoughts on native pandas try?

+7
python numpy pandas
source share
2 answers

You can use assign + mul + sum :

 df1 = df.assign(**params).mul(df).sum(1) print (df1) 0 24.1 1 21.4 2 22.6 3 23.8 4 38.4 dtype: float64 

And dot + Series constructor:

 df1 = df.dot(pd.Series(params)) print (df1) 0 24.1 1 21.4 2 22.6 3 23.8 4 38.4 dtype: float64 
+3
source share
 (pd.Series(params)*df).sum(1) Out[816]: 0 24.1 1 21.4 2 22.6 3 23.8 4 38.4 dtype: float64 

Additional Information:

 pd.Series(params) Out[817]: a 2.5 b 3.0 c 1.3 d 0.9 dtype: float64 (pd.Series(params)*df) Out[818]: abcd 0 2.5 15.0 3.9 2.7 1 5.0 12.0 2.6 1.8 2 7.5 9.0 5.2 0.9 3 10.0 9.0 3.9 0.9 4 12.5 12.0 13.0 0.9 

In your example, you can also use dot

 df.values.dot(np.array(list(params.values()))) Out[827]: array([ 24.1, 21.4, 22.6, 23.8, 38.4]) 
+5
source share

All Articles