'Adding new multiindex level
I have a DataFrame:
d = pd.DataFrame({'i1': ['A', 'B', 'C', 'D', 'E'],
'i2': ['I', 'II', 'III', 'IV', 'V'],
'val': ["lol1", "lol2", "lol3", "lol4", "lol5"]}).set_index(["i1", "i2"])
val
i1 i2
A I lol1
B II lol2
C III lol3
D IV lol4
E V lol5
I need to add new index level i3
from values [5, 10, 15]
, using pandas API, so it looks like:
val
i1 i2 i3
A I 5 lol1
10 lol1
15 lol1
B II 5 lol2
10 lol2
15 lol2
C III 5 lol3
10 lol3
15 lol3
D IV 5 lol4
10 lol4
15 lol4
E V 5 lol5
10 lol5
15 lol5
My tries(ugly):
d = np.repeat(d.reset_index().values, 3, 0)
i3 = [5, 10, 15]
r2 = np.tile(i3, 5)
r = np.concatenate([d, r2.reshape(-1, 1)], 1)
d = pd.DataFrame(r, columns=["i1", "i2", "val", "i3"])
d = d.set_index(["i1", "i2", "i3"])
Also, I've been looking towards pd.MultiIndex.from_product
, but it's going to make combinations from i1
and i2
no matter what I do.
Solution 1:[1]
Create list of tuples by values from MultiIndex
, then use DataFrame.reindex
with MultiIndex.from_tuples
:
vals = [5, 10, 15]
tups = [x + (i,) for x in d.index for i in vals]
d = d.reindex(pd.MultiIndex.from_tuples(tups, names=['i1','i2','i3']))
print (d)
val
i1 i2 i3
A I 5 lol1
10 lol1
15 lol1
B II 5 lol2
10 lol2
15 lol2
C III 5 lol3
10 lol3
15 lol3
D IV 5 lol4
10 lol4
15 lol4
E V 5 lol5
10 lol5
15 lol5
Solution 2:[2]
As an alternative to reindexing we can also create a new list column and explode.
d_new = (d.assign(i3=[[5, 10, 15]] * len(d))
.explode("i3")
.set_index("i3", append=True))
print(df_new)
# result:
val
i1 i2 i3
A I 5 lol1
10 lol1
15 lol1
B II 5 lol2
10 lol2
15 lol2
C III 5 lol3
10 lol3
15 lol3
D IV 5 lol4
10 lol4
15 lol4
E V 5 lol5
10 lol5
15 lol5
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | jezrael |
Solution 2 | mcsoini |