consider the pd.Series
s
and pd.MultiIndex
idx
idx = pd.MultiIndex.from_product([list('AB'), [1, 3], list('XY')],
names=['one', 'two', 'three'])
s = pd.Series(np.arange(8), idx)
s
one two three
A 1 X 0
Y 1
3 X 2
Y 3
B 1 X 4
Y 5
3 X 6
Y 7
dtype: int32
I want to reindex
on level='two'
with np.arange(4)
I can do it with:
s.unstack([0, 2]).reindex(np.arange(4), fill_value=0).stack().unstack([0, 1])
one two three
A 0 X 0
Y 0
1 X 0
Y 1
2 X 0
Y 0
3 X 2
Y 3
B 0 X 0
Y 0
1 X 4
Y 5
2 X 0
Y 0
3 X 6
Y 7
dtype: int32
But I'm looking for something more direct if it exists. Any ideas?
To revert the index of the dataframe from multi-index to a single index using the Pandas inbuilt function reset_index(). Returns: (Data Frame or None) DataFrame with the new index or None if inplace=True.
Reindexing the columns using axis keyword One can reindex a single column or multiple columns by using reindex() method and by specifying the axis we want to reindex. Default values in the new index that are not present in the dataframe are assigned NaN.
The reindex() function is used to conform DataFrame to new index with optional filling logic, placing NA/NaN in locations having no value in the previous index. Conform DataFrame to new index with optional filling logic, placing NA/NaN in locations having no value in the previous index.
Unfortunately if need reindex
with MultiIndex
, need all levels:
mux = pd.MultiIndex.from_product([list('AB'), np.arange(4), list('XY')],
names=['one', 'two', 'three'])
print (s.reindex(mux, fill_value=0))
one two three
A 0 X 0
Y 0
1 X 0
Y 1
2 X 0
Y 0
3 X 2
Y 3
B 0 X 0
Y 0
1 X 4
Y 5
2 X 0
Y 0
3 X 6
Y 7
dtype: int32
EDIT by comment:
idx = pd.MultiIndex.from_tuples([('A', 1, 'X'), ('B', 3, 'Y')],
names=['one', 'two', 'three'])
s = pd.Series([5,6], idx)
print (s)
one two three
A 1 X 5
B 3 Y 6
dtype: int64
mux = pd.MultiIndex.from_tuples([('A', 0, 'X'), ('A', 1, 'X'),
('A', 2, 'X'), ('A', 3, 'X'),
('B', 0, 'Y'), ('B', 1, 'Y'),
('B', 2, 'Y'), ('B', 3, 'Y')],
names=['one', 'two', 'three'])
print (s.reindex(mux, fill_value=0))
one two three
A 0 X 0
1 X 5
2 X 0
3 X 0
B 0 Y 0
1 Y 0
2 Y 0
3 Y 6
dtype: int64
Direct Solution
new_lvl = np.arange(4)
mux = [(a, b, c) for b in new_lvl for a, c in s.reset_index('two').index.unique()]
s.reindex(mux, fill_value=0).sort_index()
one two three
A 0 X 0
Y 0
1 X 0
Y 1
2 X 0
Y 0
3 X 2
Y 3
B 0 X 0
Y 0
1 X 4
Y 5
2 X 0
Y 0
3 X 6
Y 7
dtype: int64
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With