我想通过 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。
答案 0 :(得分:3)
最快的选择是应用sort()
(注意排序就地发生,所以在这种情况下不要分配回df.Rank
):
df.Rank.apply(list.sort)
或者应用带有 custom key 的 sorted()
并分配回 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}}:
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,
)
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]