自然排序 Pandas DataFrame
- 2025-02-20 09:23:00
- admin 原创
- 23
问题描述:
我有一个 pandas DataFrame,其中的索引我想自然排序。Natsort 似乎不起作用。在构建 DataFrame 之前对索引进行排序似乎没有帮助,因为我对 DataFrame 进行的操作似乎会弄乱排序过程。关于如何自然地重新排序索引,您有什么想法吗?
from natsort import natsorted
import pandas as pd
# An unsorted list of strings
a = ['0hr', '128hr', '72hr', '48hr', '96hr']
# Sorted incorrectly
b = sorted(a)
# Naturally Sorted
c = natsorted(a)
# Use a as the index for a DataFrame
df = pd.DataFrame(index=a)
# Sorted Incorrectly
df2 = df.sort()
# Natsort doesn't seem to work
df3 = natsorted(df)
print(a)
print(b)
print(c)
print(df.index)
print(df2.index)
print(df3.index)
解决方案 1:
使用sort_values
forpandas >= 1.1.0
key
使用中的新参数DataFrame.sort_values
,由于pandas 1.1.0
,我们可以直接对列进行排序,而无需使用以下方法将其设置为索引natsort.natsort_keygen
:
df = pd.DataFrame({
"time": ['0hr', '128hr', '72hr', '48hr', '96hr'],
"value": [10, 20, 30, 40, 50]
})
time value
0 0hr 10
1 128hr 20
2 72hr 30
3 48hr 40
4 96hr 50
from natsort import natsort_keygen
df.sort_values(
by="time",
key=natsort_keygen()
)
time value
0 0hr 10
3 48hr 40
2 72hr 30
4 96hr 50
1 128hr 20
解决方案 2:
现在两者都pandas
得到了支持,您现在应该参考这个其他答案并将所有赞成票发送到那里,因为它现在是正确的答案。key
`sort_values`sort_index
pandas
对于那些沉迷于旧版本或对历史感到好奇的人,我会在这里留下我的答案。
接受的答案回答了所提出的问题。我还想添加如何natsort
在 a 中的列上使用DataFrame
,因为这将是下一个要问的问题。
In [1]: from pandas import DataFrame
In [2]: from natsort import natsorted, index_natsorted, order_by_index
In [3]: df = DataFrame({'a': ['a5', 'a1', 'a10', 'a2', 'a12'], 'b': ['b1', 'b1', 'b2', 'b2', 'b1']}, index=['0hr', '128hr', '72hr', '48hr', '96hr'])
In [4]: df
Out[4]:
a b
0hr a5 b1
128hr a1 b1
72hr a10 b2
48hr a2 b2
96hr a12 b1
正如接受的答案所示,按索引排序相当简单:
In [5]: df.reindex(index=natsorted(df.index))
Out[5]:
a b
0hr a5 b1
48hr a2 b2
72hr a10 b2
96hr a12 b1
128hr a1 b1
如果您想要以相同的方式对列进行排序,则需要按照所需列重新排序的顺序对索引进行排序。natsort
提供便利的功能index_natsorted
并order_by_index
做到这一点。
In [6]: df.reindex(index=order_by_index(df.index, index_natsorted(df.a)))
Out[6]:
a b
128hr a1 b1
48hr a2 b2
0hr a5 b1
72hr a10 b2
96hr a12 b1
In [7]: df.reindex(index=order_by_index(df.index, index_natsorted(df.b)))
Out[7]:
a b
0hr a5 b1
128hr a1 b1
96hr a12 b1
72hr a10 b2
48hr a2 b2
如果要按任意数量的列(或一列和索引)重新排序,则可以使用zip
(或itertools.izip
在 Python2 上)指定对多列进行排序。给定的第一列将是主要排序列,然后是次要的,然后是第三列,等等...
In [8]: df.reindex(index=order_by_index(df.index, index_natsorted(zip(df.b, df.a))))
Out[8]:
a b
128hr a1 b1
0hr a5 b1
96hr a12 b1
48hr a2 b2
72hr a10 b2
In [9]: df.reindex(index=order_by_index(df.index, index_natsorted(zip(df.b, df.index))))
Out[9]:
a b
0hr a5 b1
96hr a12 b1
128hr a1 b1
48hr a2 b2
72hr a10 b2
这是使用对象的替代方法,开发人员Categorical
告诉我pandas
这是“正确”的方法。这需要(据我所知)pandas >= 0.16.0。目前,它仅适用于列,但显然在pandas >= 0.17.0中,他们将添加CategoricalIndex
允许在索引上使用该方法的功能。
In [1]: from pandas import DataFrame
In [2]: from natsort import natsorted
In [3]: df = DataFrame({'a': ['a5', 'a1', 'a10', 'a2', 'a12'], 'b': ['b1', 'b1', 'b2', 'b2', 'b1']}, index=['0hr', '128hr', '72hr', '48hr', '96hr'])
In [4]: df.a = df.a.astype('category')
In [5]: df.a.cat.reorder_categories(natsorted(df.a), inplace=True, ordered=True)
In [6]: df.b = df.b.astype('category')
In [8]: df.b.cat.reorder_categories(natsorted(set(df.b)), inplace=True, ordered=True)
In [9]: df.sort('a')
Out[9]:
a b
128hr a1 b1
48hr a2 b2
0hr a5 b1
72hr a10 b2
96hr a12 b1
In [10]: df.sort('b')
Out[10]:
a b
0hr a5 b1
128hr a1 b1
96hr a12 b1
72hr a10 b2
48hr a2 b2
In [11]: df.sort(['b', 'a'])
Out[11]:
a b
128hr a1 b1
0hr a5 b1
96hr a12 b1
48hr a2 b2
72hr a10 b2
该Categorical
对象允许您定义要使用的排序顺序DataFrame
。调用时给出的元素reorder_categories
必须是唯一的,因此对列“b”进行调用set
。
我让用户来决定这是否比该reindex
方法更好,因为它要求您在排序之前独立地对列数据进行排序DataFrame
(尽管我认为第二种排序相当有效)。
坦白说,我就是natsort
作者。
解决方案 3:
如果要对 df 进行排序,只需对索引或数据进行排序,然后直接分配给 df 的索引,而不是尝试将 df 作为参数传递,因为这会产生一个空列表:
In [7]:
df.index = natsorted(a)
df.index
Out[7]:
Index(['0hr', '48hr', '72hr', '96hr', '128hr'], dtype='object')
请注意,df.index = natsorted(df.index)
也有效
如果您将 df 作为参数传递,它会产生一个空列表,在这种情况下是因为 df 为空(没有列),否则它将返回已排序的列,这不是您想要的:
In [10]:
natsorted(df)
Out[10]:
[]
编辑
如果要对索引进行排序,以便数据与索引一起重新排序,那么使用reindex
:
In [13]:
df=pd.DataFrame(index=a, data=np.arange(5))
df
Out[13]:
0
0hr 0
128hr 1
72hr 2
48hr 3
96hr 4
In [14]:
df = df*2
df
Out[14]:
0
0hr 0
128hr 2
72hr 4
48hr 6
96hr 8
In [15]:
df.reindex(index=natsorted(df.index))
Out[15]:
0
0hr 0
48hr 6
72hr 4
96hr 8
128hr 2
请注意,您必须将结果分配reindex
给新的 df 或其自身,它不接受inplace
参数。
- 2025年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 项目管理必备:盘点2024年13款好用的项目管理软件
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)