Unir los valores de la columna a dict

Tengo un dict y un dataframe como los ejemplos v y df a continuación. Quiero buscar a través de los elementos en df y devolver el elemento que tiene el número máximo de valores de campo en común con los valores en el dict. En este caso, sería el elemento 3. Pensaba que tal vez utilizar aplicar con una función lambda, o transponer el df. Simplemente no puedo quedarme tranquilo. Si alguien tiene una forma elegante de hacer esto o cualquier consejo, lo apreciamos mucho.

entrada:

v={'size':1,'color':red} df: item size color 2 2 red 3 1 red Output: 3 

Cree un DataFrame de una línea y merge con el original:

 a = pd.DataFrame(v, index=[0]).merge(df)['item'] print (a) 0 3 Name: item, dtype: int64 

Otra solución con query , pero si las cadenas de valores de dict son necesarias, agregue otra " :

 v1 = {k: '"{}"'.format(v) if isinstance(v, str) else v for k, v in v.items()} print (v1) {'size': 1, 'color': '"red"'} df = df.query(' & '.join(['{}=={}'.format(i,j) for i, j in v1.items()]))['item'] print (df) 1 3 Name: item, dtype: int64 

En la salida, son posibles 3 formas: Series con más valores, un valor o vacío, por lo que se creó la función auxiliar:

 def get_val(v): x = pd.DataFrame(v, index=[0]).merge(df)['item'] if x.empty: return 'Not found' elif len(x) == 1: return x.values[0] else: return x.values.tolist() 
 print (get_val({'size':1,'color':'red'})) 3 print (get_val({'size':10,'color':'red'})) Not found print (get_val({'color':'red'})) [2, 3] 

Una solución alternativa es trabajar con diccionarios en lugar de marcos de datos:

 v = {'size': 1, 'color': 'red'} match_count = {} fields = df.columns[1:] for k, value in df.to_dict(orient='index').items(): match_count[value['item']] = sum(value[i] == v[i] for i in fields & v.keys()) 

Resultado

 print(match_count) # {2: 1, 3: 2} res = max(match_count.items(), key=lambda x: x[1]) print(res) # (3, 2)