xis
xis

Reputation: 24850

Convert part of data frame into MultiIndex in Pandas

I am having this form of data in XLS format:

+--------+---------+-------------+---------------+---------+
|   ID   |  Branch | Customer ID | Customer Name | Balance |
+--------+---------+-------------+---------------+---------+
| 111111 | Branch1 | 1           | Company A     | 10      |
+--------+---------+-------------+---------------+---------+
| 222222 | Branch2 | 2           | Company B     | 20      |
+--------+---------+-------------+---------------+---------+
| 111111 | Branch1 | 2           | Company B     | 30      |
+--------+---------+-------------+---------------+---------+
| 222222 | Branch2 | 3           | Company C     | 10      |
+--------+---------+-------------+---------------+---------+

And I would like to use Pandas to process it. Pandas would read it as a single sheet, but I would like to use MultiIndex here, like

+--------+---------+-------------+---------------+---------+
|   ID   |  Branch | Customer ID | Customer Name | Balance |
+--------+---------+-------------+---------------+---------+
|        |         | 1           | Company A     | 10      |
+ 111111 + Branch1 +-------------+---------------+---------+
|        |         | 2           | Company B     | 30      |
+--------+---------+-------------+---------------+---------+
|        |         | 2           | Company B     | 20      |
+ 222222 + Branch2 +-------------+---------------+---------+
|        |         | 3           | Company C     | 10      |
+--------+---------+-------------+---------------+---------+

Here 111111 and Branch1 are level 1 index and 1 Company A are level 2 index. Is there a built-in method to do it?

Upvotes: 1

Views: 63

Answers (1)

jezrael
jezrael

Reputation: 863256

If need only set_index and sort_index, use:

df.set_index(['ID','Branch', 'Customer ID','Customer Name'], inplace=True)
df.sort_index(inplace=True)
print (df)
                                          Balance
ID     Branch  Customer ID Customer Name         
111111 Branch1 1           Company A           10
               2           Company B           30
222222 Branch2 2           Company B           20
               3           Company C           10

But if need only two levels in MultiIndex (a,b in my solution), is necessary concatenate first with second column and third with fourth column:

df['a'] = df.ID.astype(str) + '_' + df.Branch
df['b'] = df['Customer ID'].astype(str) + '_' + df['Customer Name']
#delete original columns
df.drop(['ID','Branch', 'Customer ID','Customer Name'], axis=1, inplace=True)

df.set_index(['a','b'], inplace=True)
df.sort_index(inplace=True)
print (df)
                            Balance
a              b                   
111111_Branch1 1_Company A       10
               2_Company B       30
222222_Branch2 2_Company B       20
               3_Company C       10

If need aggregate last column by previous columns, use groupby with GroupBy.mean:

df = df.groupby(['ID','Branch', 'Customer ID','Customer Name'])['Balance'].mean().to_frame()
print (df)
                                          Balance
ID     Branch  Customer ID Customer Name         
111111 Branch1 1           Company A           10
               2           Company B           30
222222 Branch2 2           Company B           20
               3           Company C           10

If working with MultiIndex in columns need tuples for set_index:

df.columns = pd.MultiIndex.from_arrays([['a'] * 2 + ['b']* 2 + ['c'], df.columns])
print (df)
        a                    b                     c
       ID   Branch Customer ID Customer Name Balance
0  111111  Branch1           1     Company A      10
1  222222  Branch2           2     Company B      20
2  111111  Branch1           2     Company B      30
3  222222  Branch2           3     Company C      10

df.set_index([('a','ID'), ('a','Branch'), 
              ('b','Customer ID'), ('b','Customer Name')], inplace=True)
df.sort_index(inplace=True)
print (df)
                                                              c
                                                        Balance
(a, ID) (a, Branch) (b, Customer ID) (b, Customer Name)        
111111  Branch1     1                Company A               10
                    2                Company B               30
222222  Branch2     2                Company B               20
                    3                Company C               10

Upvotes: 1

Related Questions