如果之前已经解释过了,我很抱歉,但是,我仍然找不到合适的解决方案. 我对Pandas有这个简短的代码.DataFrame:

import pandas as pd


table = {
    "key4": ["key3", "command4"],
    "key2": ["key1", "command2"],
    "key3": ["cron3", "command3"],
    "key5": ["cron5", "command5"],
    "key1": ["cron1", "command1"]   
}

columns = ["trigger", "command"]
df = pd.DataFrame.from_dict(table, orient='index', columns=columns)

我希望在其父级下对每一行进行排序,换句话说,如果在触发器列中找到了key1,则应该紧跟在名称为key1的行之后进行排序.(我只希望Key1作为触发器的名称和值出现一次). 或者这是一种矫枉过正的做法,我应该try 使用不同的格式吗? 因此,print(Df)的输出应该如下所示:

     trigger    command

key3   cron3    command3
key4    key3    command4
key5   cron5    command5
key1   cron1    command1
key2    key1    command2

我是否可以以某种方式将一个函数导入df.sortValues(),从而使这种排序更具定制化?提前谢谢您.

推荐答案

您可以使用口罩和numpy.lexsort:

import numpy as np

m = df['trigger'].isin(df.index)
key = df['trigger'].where(m, df.index)

out = df.iloc[np.lexsort([m, key])]

或者是纯Pandas (不那么优雅的IMO,但如果你需要定制订单,则更灵活;见下文):

out = (df
   .assign(m=df['trigger'].isin(df.index),
           key=lambda d: d['trigger'].where(m, d.index))
   .sort_values(by=['key', 'm'])
   .drop(columns=['m', 'key'])
)

输出:

     trigger   command
key1   cron1  command1
key2    key1  command2
key3   cron3  command3
key4    key3  command4
key5   cron5  command5

中间体:

# before sorting
     trigger   command      m   key
key4    key3  command4   True  key3
key2    key1  command2   True  key1
key3   cron3  command3  False  key3
key5   cron5  command5  False  key5
key1   cron1  command1  False  key1

# after sorting
     trigger   command      m   key
key1   cron1  command1  False  key1
key2    key1  command2   True  key1
key3   cron3  command3  False  key3
key4    key3  command4   True  key3
key5   cron5  command5  False  key5

如果要保持组的原始顺序(key3 -> key5 -> key1):

out = (df
   .assign(m=df['trigger'].isin(df.index),
           key=lambda d: pd.Categorical(d['trigger'].where(m, d.index),
                                       categories=d.index[~d['m']].unique(),
                                        ordered=True)
          )
   .sort_values(by=['key', 'm'])
   .drop(columns=['m', 'key'])
)

变体:

m = df['trigger'].isin(df.index)
key = df['trigger'].where(m, df.index)
order = df.index[~m].unique()

tmp = df.assign(key=pd.Categorical(key, categories=order, ordered=True))

out = (pd.concat([tmp[~m], tmp[m]]).sort_values(by='key', kind='stable')
         .drop(columns='key')
      )

输出:

     trigger   command
key3   cron3  command3
key4    key3  command4
key5   cron5  command5
key1   cron1  command1
key2    key1  command2

Python相关问答推荐

根据条件将新值添加到下面的行或下面新创建的行中

Pystata:从Python并行运行stata实例

为什么我的Python代码在if-else声明中的行之前执行if-else声明中的行?

max_of_three使用First_select、second_select、

rame中不兼容的d类型

如何获取TFIDF Transformer中的值?

Django REST Framework:无法正确地将值注释到多对多模型,不断得到错误字段名称字段对模型无效'<><>

当递归函数的返回值未绑定到变量时,非局部变量不更新:

从嵌套的yaml创建一个嵌套字符串,后面跟着点

Django—cte给出:QuerySet对象没有属性with_cte''''

Python Pandas获取层次路径直到顶层管理

dask无groupby(ddf. agg([min,max])?''''

在Python中使用yaml渲染(多行字符串)

Odoo16:模板中使用的docs变量在哪里定义?

在Django中重命名我的表后,旧表中的项目不会被移动或删除

pytest、xdist和共享生成的文件依赖项

在matplotlib中重叠极 map 以创建径向龙卷风图

大Pandas 中的群体交叉融合

Python:使用asyncio.StreamReader.readline()读取长行

Fake pathlib.使用pyfakefs的类变量中的路径'