Reputation: 503
Consider the following DataFrame:
import numpy as np
import pandas as pd
arrays = [['foo', 'foo', 'foo', 'bar', 'bar', 'bar'],
['A', 'B', 'C', 'A', 'B', 'C']]
tuples = list(zip(*arrays))
index_values = pd.MultiIndex.from_tuples(tuples)
df = pd.DataFrame(np.random.rand(6), index = index_values)
print(df)
0
foo A 0.726699
B 0.001700
C 0.936495
bar A 0.298490
B 0.167234
C 0.476725
Say I want to scale df with the following values:
df_scale = pd.DataFrame([0,1,4], index=['A','B','C'])
print(df_scale)
0
A 0
B 1
C 4
That is, I want all A's to be multiplied by 0, all B's by 1, and all C's by 4.
Currently, I use the following approach:
df_new = df.copy()
list_df_new_index = list(df_new.index)
for index in list_df_new_index:
cntr, prod = index
df_new.loc[cntr, prod] = df_new.loc[cntr, prod]*df_scale.loc[prod]
print(df_new)
0
foo A 0.000000
B 0.001700
C 3.745981
bar A 0.000000
B 0.167234
C 1.906900
While this works, I can't help but think there is a functionality within pandas that would allow me to do just that.
I went through the answers on Select rows in pandas MultiIndex DataFrame.
At first I thought I could use df.xs(), but if I understand correctly this only allows me to select and not change values.
Next I looked into pd.IndexSlice(), but I don't see how I can use this to change multiple values.
Does pandas offer the functionality of changing multiple values in a lower level of a MultiIndex DataFrame?
Upvotes: 1
Views: 81
Reputation: 862641
You can multiple by DataFrame.mul
:
df = df.mul(df_scale, level=1, axis=0)
#if want multiple by column 0
#df = df.mul(df_scale[0], level=1, axis=0)
print (df)
0
foo A 0.000000
B 0.393081
C 2.495880
bar A 0.000000
B 0.880499
C 1.196688
Upvotes: 1