Soerendip
Soerendip

Reputation: 9148

Return Pandas multiindex as list of tuples?

It is possible to create a Multiindex from a list of tuples. I wonder how to do the reverse? Consider the follwing multi-index:

MultiIndex(levels=[['N', 'R'], ['N', 'R', 'S'], ['N', 'R', 'S'], ['N', 'R', 'S'], ['N', 'R', 'S'], ['N', 'R', 'S'], ['R', 'S'], ['N', 'R', 'S']],
           labels=[[0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 2, 1, 1, 2, 1, 2, 2, 2, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [0, 0, 0, 2, 2, 2, 2, 1, 0, 1, 2, 2, 2, 2, 0, 0, 0, 2, 0, 2, 0, 2, 1, 1, 0, 2, 0, 2, 0, 1, 0, 2, 2, 2, 1, 2, 1, 2, 2, 2, 1, 0, 0, 2, 0, 1, 0, 2, 2, 2, 0, 1, 1, 2, 1, 1, 2, 1, 2, 2, 0, 1, 2, 1, 2, 1, 1, 1], [2, 0, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 2, 1, 2, 2, 1, 1, 2, 1, 2, 2, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1, 1], [0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 2, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 2, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 0, 2, 0, 2, 2, 1, 2, 1], [0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 2, 1, 2, 1, 2, 2, 2, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1], [1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0], [0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 1, 2, 1, 2, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]],
           names=['AMP', 'CZ', 'FOX', 'CRO', 'MER', 'GM', 'CIP', 'SXT'])

I want to return a list of tuples that I would use to make a selection with DataFrame.loc[] e.g. [('S', 'S', 'S', 'S', 'S', 'S', 'S, 'S'), ...]

Something I would expect df.index.as_tuples() to do, which unfortunately does not exist.

Upvotes: 14

Views: 14693

Answers (3)

cs95
cs95

Reputation: 402383

Either df.index.tolist() or df.index.values will do.


From pandas >= 0.24, you can also use df.index.to_numpy().

Upvotes: 21

jezrael
jezrael

Reputation: 862581

In pandas 0.24+ is possible use MultiIndex.to_flat_index:

print (df.index.to_flat_index())

Sample:

arrays = [['bar', 'bar', 'baz', 'baz', 'foo', 'foo', 'qux', 'qux'],
          ['one', 'two', 'one', 'two', 'one', 'two', 'one', 'two']]
tuples = list(zip(*arrays))
index = pd.MultiIndex.from_tuples(tuples, names=['first', 'second'])
s = pd.Series(np.random.randn(8), index=index)

print (s.index.to_flat_index())
Index([('bar', 'one'), ('bar', 'two'), ('baz', 'one'), ('baz', 'two'),
       ('foo', 'one'), ('foo', 'two'), ('qux', 'one'), ('qux', 'two')],
      dtype='object')

Upvotes: 5

Soerendip
Soerendip

Reputation: 9148

This can be done by calling the method to_native_types()

df.index.to_native_types()
> array([('N', 'N', 'N', 'S', 'N', 'N', 'S', 'N'),
   ('R', 'S', 'N', 'N', 'N', 'S', 'S', 'S'),
   ('R', 'S', 'N', 'S', 'N', 'S', 'S', 'S'),
   ('R', 'S', 'S', 'S', 'N', 'S', 'S', 'S'),
   ('R', 'S', 'S', 'N', 'S', 'S', 'S', 'S'),
   ('R', 'S', 'S', 'S', 'S', 'S', 'S', 'S'),
   ('R', 'S', 'S', 'S', 'S', 'S', 'R', 'S'),
   ('R', 'S', 'R', 'S', 'S', 'S', 'S', 'S'),
   ...], dtype=object)

Upvotes: 2

Related Questions