这是我的previous
问题的扩展。
下面是df:
In [28]: df = pd.DataFrame({'A':['a','b:all:c','all:1:3','c','d','e'], '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 [34]: df.columns = pd.MultiIndex.from_product([df.columns, ['E']])
In [35]: df
Out[35]:
A D
E E
0 a {'value': '126', 'perc': None, 'unit': None}
1 b:all:c {'value': 324, 'perc': None, 'unit': None}
2 all:1:3 {'value': 'N/A', 'perc': None, 'unit': None}
3 c {}
4 d {'value': '100', 'perc': None, 'unit': None}
5 e NaN
我需要根据字典中的值键对索引为(D,E)
的多级列进行降序排序。
但是我需要保留所有先前列中包含子字符串all
的行。
如您所见,值键可以具有混合数据类型的值,例如int,字符串或空值(例如{}或NaN)。
N / A和Nan值应始终在排序后最后显示(升序和降序)。
因此,预期输出将为:
In [38]: df1 = pd.DataFrame({'A':['a','b:all:c','all:1:3','d','c','e'], '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": No
...: ne},{}, np.nan]})
...:
In [40]: df1.columns = pd.MultiIndex.from_product([df1.columns, ['E']])
In [41]: df1
Out[41]:
A D
E E
0 a {'value': '126', 'perc': None, 'unit': None}
1 b:all:c {'value': 324, 'perc': None, 'unit': None}
2 all:1:3 {'value': 'N/A', 'perc': None, 'unit': None}
3 d {'value': '100', 'perc': None, 'unit': None}
4 c {}
5 e NaN
答案 0 :(得分:1)
想法是先查找all
列之前(D, E)
的所有行以进行屏蔽,然后将不匹配的行过滤到df1
,对用于映射原始索引值的索引值进行排序和提取,并最后排序:
print (df)
mask = (df.iloc[:, : df.columns.get_loc(('D','E'))]
.apply(lambda x: x.astype(str).str.contains('all'))
.any(axis=1))
print (mask)
0 False
1 True
2 True
3 False
4 False
5 False
dtype: bool
df1 = df[~mask].copy()
df1['tmp'] = pd.to_numeric(df1[('D','E')].str.get('value'), errors='coerce')
idx = df1.sort_values('tmp', ascending=False).index
print (idx)
Int64Index([0, 4, 3, 5], dtype='int64')
d = dict(zip(df.index[~mask], idx))
print (d)
{0: 0, 3: 4, 4: 3, 5: 5}
df = df.set_index(df.rename(d).index).sort_index()
print (df)
A D
E E
0 a {'value': '126', 'perc': None, 'unit': None}
1 b:all:c {'value': 324, 'perc': None, 'unit': None}
2 all:1:3 {'value': 'N/A', 'perc': None, 'unit': None
3 d {'value': '100', 'perc': None, 'unit': None}
4 c {}
5 e NaN