带有嵌套列表的 Python 熊猫 sort_values()

时间:2021-06-13 14:49:57

标签: python pandas

我想通过 Pandas 对 pyhon 中的嵌套字典进行排序。

import pandas as pd 

# Data structure (nested list):
# {
#   category_name: [[rank, id], ...],
#   ...
# }

all_categories = {
    "category_name1": [[2, 12345], [1, 32512], [3, 32382]],
    "category_name2": [[3, 12345], [9, 25318], [1, 24623]]
}

df = pd.DataFrame(all_categories.items(), columns=['Category', 'Rank'])
df.sort_values(['Rank'], ascending=True, inplace=True) # this only sorts the list of lists

谁能告诉我如何才能达到我的目标?我想不通。通过熊猫,可以通过第二列 sort_values(),但我不知道如何对嵌套的 dict/list 进行排序。

我想按排名升序排序,而不是 id。

4 个答案:

答案 0 :(得分:3)

最快的选择是应用sort()(注意排序就地发生,所以在这种情况下不要分配回df.Rank):

df.Rank.apply(list.sort)

或者应用带有 custom keysorted() 并分配回 df.Rank

df.Rank = df.Rank.apply(lambda row: sorted(row, key=lambda x: x[0]))

两种情况下的输出:

>>> df
         Category                                  Rank
0  category_name1  [[1, 32512], [2, 12345], [3, 32382]]
1  category_name2  [[1, 24623], [3, 12345], [9, 25318]]

这是sort() vs sorted() vs explode()的{​​{3}}:

perfplot

import perfplot

def explode(df):
    df = df.explode('Rank')
    df['rank_num'] = df.Rank.str[0]
    df = df.sort_values(['Category', 'rank_num']).groupby('Category', as_index=False).agg(list)
    return df

def apply_sort(df):
    df.Rank.apply(list.sort)
    return df

def apply_sorted(df):
    df.Rank = df.Rank.apply(lambda row: sorted(row, key=lambda x: x[0]))
    return df

perfplot.show(
    setup=lambda n: pd.concat([df] * n),
    n_range=[2 ** k for k in range(25)],
    kernels=[explode, apply_sort, apply_sorted],
    equality_check=None,
)

要按列表长度过滤行,请使用 timing resultsloc[] 屏蔽行:

mask = df.Rank.str.len().ge(10)
df.loc[mask, 'Rank'].apply(list.sort)

答案 1 :(得分:1)

试试

objectContaining

听写

df = pd.DataFrame(all_categories.items(), columns=['Category', 'Rank']).explode('Rank')
df['Rank'] = df['Rank'].apply(lambda x: sorted(x))

df = df.groupby('Category').agg(list).reset_index()

答案 2 :(得分:0)

试试:

df = pd.DataFrame(all_categories.items(), columns=['Category', 'Rank'])
df.set_index('Rank', inplace=True)
df.sort_index(inplace=True)
df.reset_index(inplace=True)

或者:

df = pd.DataFrame(all_categories.items(), columns=['Category', 'Rank'])
df = df.set_index('Rank').sort_index().reset_index()

答案 3 :(得分:0)

使用 df.explode 然后对值进行排序效率更高。它将被矢量化。

df = df.explode('Rank')
df['rank_num'] = df.Rank.str[0]

df.sort_values(['Category', 'rank_num'])
  .groupby('Category', as_index=False)
  .agg(list)

输出

         Category                                  Rank   rank_num
0  category_name1  [[1, 32512], [2, 12345], [3, 32382]]  [1, 2, 3]
1  category_name2  [[1, 24623], [3, 12345], [9, 25318]]  [1, 3, 9]