nueva - Python Pandas: cómo dividir un diccionario ordenado en una columna de un marco de datos
nueva columna en pandas (2)
Esto debería funcionar:
In [1]: import pandas as pd
In [2]: import operator
In [3]: df = pd.DataFrame({ ''id'' : [0,1,2,3],
...: ''asn'' : [3320, 47886, 47601, 33438],
...: ''orgs'' : [{''Deutsche Telekom AG'': 2288}, {''Joyent'': 16, ''Equinix (Netherlands) B.V.'': 7}, {''fusion services'': 1024, ''GCE Global Maritime'':16859}, {''Highwinds Network Group'': 893}]
...: })
In [4]: df.orgs, df[''value''] = zip(*df.orgs.apply(lambda x : sorted(x.items(),key=operator.itemgetter(1),reverse=True)[0]))
In [5]: df
Out[5]:
asn id orgs value
0 3320 0 Deutsche Telekom AG 2288
1 47886 1 Joyent 16
2 47601 2 GCE Global Maritime 16859
3 33438 3 Highwinds Network Group 893
Utilicé zip(* <first element of sorted dict items>)
y los df.orgs
a df.orgs
y df.value
.
Para diccionarios vacíos:
In [3]: df = pd.DataFrame({ ''id'' : [0,1,2,3],
...: ''asn'' : [3320, 47886, 47601, 33438],
...: ''orgs'' : [{''Deutsche Telekom AG'': 2288}, {''Joyent'': 16, ''Equinix (Netherlands) B.V.'': 7}, {''fusion services'': 1024, ''GCE Global Maritime'':16859}, {}]
...: })
In [4]: df.orgs.apply(lambda x : sorted(x.items(),key=operator.itemgetter(1),reverse=True)[0] if len(x) else ('''',''''))
Out[4]:
0 (Deutsche Telekom AG, 2288)
1 (Joyent, 16)
2 (GCE Global Maritime, 16859)
3 (, )
Name: orgs, dtype: object
In [5]: df.orgs, df[''value''] = zip(*df.orgs.apply(lambda x : sorted(x.items(),key=operator.itemgetter(1),reverse=True)[0] if len(x) else ('''','''')))
In [6]: df
Out[6]:
asn id orgs value
0 3320 0 Deutsche Telekom AG 2288
1 47886 1 Joyent 16
2 47601 2 GCE Global Maritime 16859
3 33438 3
Tengo un DataFrame como este:
id asn orgs
0 3320 {''Deutsche Telekom AG'': 2288}
1 47886 {''Joyent'': 16, ''Equinix (Netherlands) B.V.'': 7}
2 47601 {''fusion services'': 1024, ''GCE Global Maritime'':16859}
3 33438 {''Highwinds Network Group'': 893}
Me gustaría ordenar la columna ''orgs'' que en realidad es un diccionario y luego extraer obtener el par (k, v) con los valores más altos en dos columnas diferentes. Me gusta esto:
id asn org value
0 3320 ''Deutsche Telekom AG'' 2288
1 47886 ''Joyent'' 16
2 47601 ''GCE Global Maritime'' 16859
3 33438 ''Highwinds Network Group'' 893
Actualmente estoy ejecutando este código pero no ordena correctamente, y luego no estoy seguro de cómo extraer el par con el valor más alto.
df.orgs.apply(lambda x : sorted(x.items(),key=operator.itemgetter(1),reverse=True))
que me dio una lista como esta:
id asn orgs
0 3320 [(''Deutsche Telekom AG'', 2288)]
1 47886 [(''Joyent'', 16),( ''Equinix (Netherlands) B.V.'', 7)]
2 47601 [(''GCE Global Maritime'',16859),(''fusion services'', 1024)]
3 33438 [(''Highwinds Network Group'', 893)]
Ahora, ¿cómo puedo poner la clave y el valor de la más alta en dos columnas separadas? ¿Alguien puede ayudar?
Otro enfoque define una función que simplemente llama a min
en el dict y devuelve una serie para que pueda asignar varias columnas (cuerpo de la función tomado de la respuesta de @Alex Martelli ):
In [17]:
def func(x):
k = min(x, key=x.get)
return pd.Series([k, x[k]])
df[[''orgs'', ''value'']] = df[''orgs''].apply(func)
df
Out[17]:
asn id orgs value
0 3320 0 Deutsche Telekom AG 2288
1 47886 1 Equinix (Netherlands) B.V. 7
2 47601 2 fusion services 1024
3 33438 3 Highwinds Network Group 893
EDITAR
Si tus datos tienen dicss vacíos, entonces puedes probar el len
:
In [34]:
df = pd.DataFrame({''id'':[0,1,2,3,4],
''asn'':[3320,47886,47601,33438,56],
''orgs'':[{''Deutsche Telekom AG'': 2288},
{''Joyent'': 16, ''Equinix (Netherlands) B.V.'': 7},
{''fusion services'': 1024, ''GCE Global Maritime'':16859},
{''Highwinds Network Group'': 893},{}]})
df
Out[34]:
asn id orgs
0 3320 0 {''Deutsche Telekom AG'': 2288}
1 47886 1 {''Equinix (Netherlands) B.V.'': 7, ''Joyent'': 16}
2 47601 2 {''GCE Global Maritime'': 16859, ''fusion service...
3 33438 3 {''Highwinds Network Group'': 893}
4 56 4 {}
In [36]:
def func(x):
if len(x) > 0:
k = min(x, key=x.get)
return pd.Series([k, x[k]])
return pd.Series([np.NaN, np.NaN])
df[[''orgs'', ''value'']] = df[''orgs''].apply(func)
df
Out[36]:
asn id orgs value
0 3320 0 Deutsche Telekom AG 2288
1 47886 1 Equinix (Netherlands) B.V. 7
2 47601 2 fusion services 1024
3 33438 3 Highwinds Network Group 893
4 56 4 NaN NaN