首页 > 解决方案 > Pandas:使用混合数据类型对多索引数据框的多级列进行排序

问题描述

下面是我的数据框:

In [2804]: df = pd.DataFrame({'A':[1,2,3,4,5,6], 'D':[{"value": '126', "perc": None, "unit": None}, {"value": 324, "perc": None, "unit": None}, {"value": 'N/A', "perc": None, "unit": None}, {}, {"value": '100', "perc": None, "unit": None}, np.nan]})

In [2794]: df.columns = pd.MultiIndex.from_product([df.columns, ['E']])

In [2807]: df
Out[2807]: 
   A                                             D
   E                                             E
0  1  {'value': '126', 'perc': None, 'unit': None}
1  2    {'value': 324, 'perc': None, 'unit': None}
2  3  {'value': 'N/A', 'perc': None, 'unit': None}
3  4                                            {}
4  5  {'value': '100', 'perc': None, 'unit': None}
5  6                                           NaN

我需要根据key from(D,E)以降序对具有索引的多级列进行排序。valuedict

如您所见value,键可以具有混合数据类型中的值,例如int, string或 空{}, 或NaN

N/A并且Nan值应始终在排序后出现(asc 和 desc)。

预期输出:

In [2814]: df1 = pd.DataFrame({'A':[2,1,5,3,4,6], 'D':[{"value": 324, "perc": None, "unit": None}, {"value": '126', "perc": None, "unit": None}, {"value": '100', "perc": None, "unit": None}, {"value": 'N/A', "perc": None, "unit": None}, {},np.nan]})

In [2799]: df1.columns = pd.MultiIndex.from_product([df1.columns, ['E']])

In [2811]: df1
Out[2811]: 
   A                                             D
   E                                             E
0  2    {'value': 324, 'perc': None, 'unit': None}
1  1  {'value': '126', 'perc': None, 'unit': None}
2  5  {'value': '100', 'perc': None, 'unit': None}
3  3  {'value': 'N/A', 'perc': None, 'unit': None}
4  4                                            {}
5  6                                           NaN

标签: pythonpython-3.xpandasdataframe

解决方案


创建由数字填充的辅助列并按此列排序:

df['tmp'] = pd.to_numeric(df[('D','E')].str.get('value'), errors='coerce')
df1 = df.sort_values('tmp', ascending=False).drop('tmp', axis=1)
print (df1)
   A                                             D
   E                                             E
1  2    {'value': 324, 'perc': None, 'unit': None}
0  1  {'value': '126', 'perc': None, 'unit': None}
4  5  {'value': '100', 'perc': None, 'unit': None}
2  3  {'value': 'N/A', 'perc': None, 'unit': None}
3  4                                            {}
5  6                                           NaN

df1 = df.sort_values('tmp').drop('tmp', axis=1)
print (df1)
   A                                             D
   E                                             E
4  5  {'value': '100', 'perc': None, 'unit': None}
0  1  {'value': '126', 'perc': None, 'unit': None}
1  2    {'value': 324, 'perc': None, 'unit': None}
2  3  {'value': 'N/A', 'perc': None, 'unit': None}
3  4                                            {}
5  6                                           NaN
    

推荐阅读