Búsqueda de Pandas MultiIndex con matrices Numpy

Estoy trabajando con un dataframe de pandas que representa un gráfico. El dataframe está indexado por un MultiIndex que indica los puntos finales del nodo.

Preparar:

import pandas as pd import numpy as np import itertools as it edges = list(it.combinations([1, 2, 3, 4], 2)) # Define a dataframe to represent a graph index = pd.MultiIndex.from_tuples(edges, names=['u', 'v']) df = pd.DataFrame.from_dict({ 'edge_id': list(range(len(edges))), 'edge_weight': np.random.RandomState(0).rand(len(edges)), }) df.index = index print(df) ## -- End pasted text -- edge_id edge_weight uv 1 2 0 0.5488 3 1 0.7152 4 2 0.6028 2 3 3 0.5449 4 4 0.4237 3 4 5 0.6459 

Quiero poder indexar en el gráfico usando un subconjunto de borde, por lo que he elegido usar un MultiIndex . Soy capaz de hacer esto bien siempre y cuando la entrada a df.loc sea ​​una lista de tuplas.

 # Select subset of graph using list-of-tuple indexing edge_subset1 = [edges[x] for x in [0, 3, 2]] df.loc[edge_subset1] ## -- End pasted text -- edge_id edge_weight uv 1 2 0 0.5488 2 3 3 0.5449 1 4 2 0.6028 

Sin embargo, cuando mi lista de bordes es una matriz numpy (como suele serlo) o una lista de listas, parece que no df.loc usar la propiedad df.loc .

 # Why can't I do this if `edge_subset2` is a numpy array? edge_subset2 = np.array(edge_subset1) df.loc[edge_subset2] ## -- End pasted text -- TypeError: unhashable type: 'numpy.ndarray' 

Estaría bien si pudiera simplemente arr.tolist() , pero esto resulta en un error aparentemente diferente.

 # Why can't I do this if `edge_subset2` is a numpy array? # or if `edge_subset3` is a list-of-lists? edge_subset3 = edge_subset2.tolist() df.loc[edge_subset3] ## -- End pasted text -- TypeError: '[1, 2]' is an invalid key 

Es realmente list(map(tuple, arr.tolist())) tener que usar list(map(tuple, arr.tolist())) cada vez que quiero seleccionar un subconjunto. Sería bueno si hubiera otra manera de hacer esto.

Las principales misiones son:

  • ¿Por qué no puedo usar una matriz .loc con .loc ? ¿Se debe a que bajo el capó se está utilizando un diccionario para asignar las tags de múltiples índices a los índices posicionales?

  • ¿Por qué una lista de listas da un error diferente? Tal vez sea realmente el mismo problema, solo que haya sido captado de otra manera.

  • ¿Hay otra forma (idealmente menos verbosa) de buscar un subconjunto de un dataframe con una gran cantidad de tags de múltiples índices que no conozco?

Las claves de un diccionario son inmutables, es por eso que básicamente no puedes usar una lista de listas para acceder a múltiples índices.

Para poder acceder a los datos de indexación múltiple usando loc , necesita convertir su matriz numpy a una lista de tuplas; Las tuplas son inmutables, una forma de hacerlo es usando el map como mencionaste

Si desea evitar el uso del mapa y está leyendo los bordes de un archivo csv, puede leerlos en un dataframe y luego utilizar to_records con el atributo de index establecido en False . Otra forma podría ser mediante la creación de un índice múltiple desde el ndarray pero tiene que transponer la lista antes de pasarla para que cada nivel sea una lista en la matriz

 import pandas as pd df1 = df.loc[pd.MultiIndex.from_arrays(edge_subset2.T)] print(df1) #outputs edge_id edge_weight ------ --------- ------------- (1, 2) 0 0.548814 (2, 3) 3 0.544883 (1, 4) 2 0.602763 

Encontré el artículo avanzado de indexación múltiple en la documentación de pandas muy útil