簡體   English   中英

如何對 Pandas Dataframe 的 MultiIndex 進行自定義排序?

[英]How do I custom sort against a Pandas Dataframe's MultiIndex?

我有一個如下所示的 Pandas dataframe。

data = pd.DataFrame({
    'x': [10, 9, 8, 4],
    'y': [1, 2, 3, 4],
})

data.index = pd.MultiIndex.from_tuples([
    ('high', 'high'), 
    ('high', 'low'), 
    ('low', 'high'), 
    ('low', 'low')
], names=['score', 'grade'])

我想根據 2 index scoregrade對這個 dataframe 進行排序。 我想要這樣的排序,即兩個指數的low先於high 我該怎么做呢?

我在下面嘗試了這段代碼,但只有第一個索引score是根據需要排序的。

data.sort_index(level=[0, 1], key=lambda s: sorted(s, reverse=True))

關於如何針對多個索引自定義排序的任何想法? 我嘗試創建自定義排序 function 進行調試。 下面是我的嘗試。

def do_sort(s):
    print(s)
    
    r = pd.Index(sorted(s, reverse=True), name=s.name)
    print(r)
    
    return r

data.sort_index(level=[0, 1], key=do_sort)

輸出結果符合預期。 這些值按照我的需要進行排序。

-- before and after for score
Index(['high', 'high', 'low', 'low'], dtype='object', name='score')
Index(['low', 'low', 'high', 'high'], dtype='object', name='score')

-- before and after for grade
Index(['high', 'low', 'high', 'low'], dtype='object', name='grade')
Index(['low', 'low', 'high', 'high'], dtype='object', name='grade')

實際上, gradescore實際上是highmediumlow的值。 為了簡潔起見,我在這里low high 這是真正反映我的數據的示例。

data = pd.DataFrame({
    'x': [10, 9, 8, 7, 6, 5, 4, 3, 1],
    'y': [1, 2, 3, 4, 5, 6, 7, 8, 9],
})

data.index = pd.MultiIndex.from_tuples([
    ('high', 'high'), 
    ('high', 'medium'), 
    ('high', 'low'),
    ('medium', 'high'),
    ('medium', 'medium'),
    ('medium', 'low'),
    ('low', 'high'), 
    ('low', 'medium'),
    ('low', 'low')
], names=['score', 'grade'])

def do_sort(s):
    mapping = {
        'low': 0,
        'medium': 1,
        'high': 2
    }
    
    print(s)
    
    r = [(v, mapping[v]) for v in s]
    r = sorted(r, key=lambda tup: tup[1])
    r = pd.Index([tup[0] for tup in r], name=s.name)
    
    print(r)
    print('-' * 15)
    
    return r

data.sort_index(level=[0, 1], key=do_sort)

記錄的 output 如下。 如您所見,我得到了正確的排序(低、中、高),但score索引僅按需要排序。

-- before/after for score
Index(['high', 'high', 'high', 'medium', 'medium', 'medium', 'low', 'low',
       'low'],
      dtype='object', name='score')
Index(['low', 'low', 'low', 'medium', 'medium', 'medium', 'high', 'high',
       'high'],
      dtype='object', name='score')
-- before/after for grade
Index(['high', 'medium', 'low', 'high', 'medium', 'low', 'high', 'medium',
       'low'],
      dtype='object', name='grade')
Index(['low', 'low', 'low', 'medium', 'medium', 'medium', 'high', 'high',
       'high'],
      dtype='object', name='grade')

嘗試ascending

out = data.sort_index(ascending=[True,False])
              x  y
score grade       
high  low     9  2
      high   10  1
low   low     4  4
      high    8  3
#data.sort_index(ascending=[False,False])
#              x  y
#score grade       
#low   low     4  4
#      high    8  3
#high  low     9  2
#      high   10  1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM