如何按列分组,然后在python中的组内重新排序列
Posted
技术标签:
【中文标题】如何按列分组,然后在python中的组内重新排序列【英文标题】:How to groupby column and then reorder columns within groups in python 【发布时间】:2022-01-02 14:40:54 【问题描述】:我有以下分组数据框:
Value1 Value2
Category
------------------------------------
0 0 62 44
1 55 46
2 73 75
1 0 61 49
1 55 46
2 34 35
2 0 62 48
1 55 46
2 44 25
我想为每个组将“Value1”列重新排序为升序,同时保持“Category”列的顺序。目标是“类别”0 将对应于最低的“Value1”值,“类别”5 将对应于最高的“Value1”值。 “Value2”值将对应于它们对应的原始“Value1”值。这是我要生成的输出数据框:
Value1 Value2
Category
------------------------------------
0 0 55 46
1 62 44
2 73 75
1 0 34 35
1 55 46
2 61 49
2 0 44 25
1 55 46
2 62 48
如何在 python 中完成此操作?我尝试过使用.reset_index()
和`.sort_values(),但我只是没有得到我想要的分组数据框。我试过了:
df.sort_values(['Value1'],ascending=True).groupby('Category')
但这只会产生:<pandas.core.groupby.generic.DataFrameGroupBy object at ...>
,这没什么用。
【问题讨论】:
【参考方案1】:使用带有索引名称的sort_values
的一种方式:
tmp = df.index.names
df.index.names = ["tmp", "Category"]
new_df = df.sort_values(["tmp", "Value1"])
new_df.index = df.index.rename(tmp)
print(new_df)
输出:
Value1 Value2
Category
0 0 55 46
1 62 44
2 73 75
1 0 34 35
1 55 46
2 61 49
2 0 44 25
1 55 46
2 62 48
【讨论】:
【参考方案2】:您可以按如下方式应用它:
import pandas as pd
df = pd.DataFrame('col1': [0, 1, 2, 0, 1, 2], 'col2': [8, 9, 6, 40, 3, 20], 'col3': [5, 6, 0, 40, 3, 20])
sorted_df = df.sort_values(['col2'], ascending=True)
df[['col2', 'col3']] = sorted_df[['col2', 'col3']].values
print(df)
输出:
col1 col2 col3
0 0 3 3
1 1 6 0
2 2 8 5
3 0 9 6
4 1 20 20
5 2 40 40
【讨论】:
我冒昧地简化了您的列分配;)(并为您的答案+1)【参考方案3】:您可以根据值和第一级索引对数据框进行排序:
>>> df = (df.sort_values(by=['Value1', 'Value2'])
.sort_index(level=0, sort_remaining=False)
)
Value1 Value2
Category
0 1 55 46
0 62 44
2 73 75
1 2 34 35
1 55 46
0 61 49
2 2 44 25
1 55 46
0 62 48
然后您需要使用cumcount
每组重写level1:
df.sort_values(by=['Value1', 'Value2']).sort_index(level=0, sort_remaining=False)
idx = pd.MultiIndex.from_arrays([df.index.get_level_values(0),
pd.Series(range(len(df))).groupby(df.index.get_level_values(0)).cumcount()],
names=(None, 'Category')
)
df.index = idx
输出:
Value1 Value2
Category
0 0 55 46
1 62 44
2 73 75
1 0 34 35
1 55 46
2 61 49
2 0 44 25
1 55 46
2 62 48
【讨论】:
【参考方案4】:一行解决方案应该是DataFrame.rename_axis
与DataFrame.sort_values
和DataFrame.set_index
:
df = df.rename_axis(index=None:'tmp').sort_values(['tmp', "Value1"]).set_index(df.index)
print (df)
Value1 Value2
Category
0 0 55 46
1 62 44
2 73 75
1 0 34 35
1 55 46
2 61 49
2 0 44 25
1 55 46
2 62 48
【讨论】:
我没有按要求重置 level1 ;) @mozway - 把最后一个rename_axis
改成set_index
解决这个问题以上是关于如何按列分组,然后在python中的组内重新排序列的主要内容,如果未能解决你的问题,请参考以下文章