如何按分层类别结构中的值对 pandas 中的数据框进行排序

2024-05-06

我有一个 pandas 数据框。

pd.DataFrame({
    "category": ["Transport", "Transport : Car", "Transport : Train", "Household", "Household : Utilities", "Household : Utilities : Water", "Household : Utilities : Electric", "Household : Cleaning", "Household : Cleaning : Bathroom", "Household : Cleaning : Kitchen", "Household : Rent", "Living", "Living : Other", "Living : Food", "Living : Something", "Living : Anitsomething"],
    "amount": [5000, 4900, 100, 1100, 600, 400, 200, 100, 75, 25, 400, 250, 150, 100, 1000, -1000]
})

类别和子类别用冒号分隔。

我试图按数量(绝对值)降序对这个数据框进行排序。同时尊重等级分组。 IE。排序结果应该是这样的

Transport                           5000
Transport : Car                     4900
Transport : Train                   100
Household                           1600
Household : Utilities               600
Household : Utilities : Water       400
Household : Utilities : Electric    200
Household : Rent                    400
Living                              250
Living : Something                  1000
Living : Antisomething              -1000
Living : Other                      150
Living : Food                       100

我可以以极其低效的方式递归地执行此操作。超级慢但是有效。

def sort_hierachical(self, full_df, name_column, sort_column, parent="", level=0):
    result_df = pd.DataFrame(columns=full_df.columns)
    part_df = full_df.loc[(full_df[name_column].str.count(':') == level) & (full_df[name_column].str.startswith(parent)), :]
    part_df['abs'] = part_df[sort_column].abs()
    part_df = part_df.sort_values('abs', ascending=False)
    for _, row in part_df.iterrows():
        category = row[name_column]
        row_df = pd.DataFrame(columns = full_df.columns).append(row)
        child_rows = self.sort_hierachical(full_df, name_column, sort_column, category, level+1)
        if not child_rows.empty:
            result_df = pd.concat([result_df, row_df], sort=False)
            result_df = pd.concat([result_df, child_rows], sort=False)
        else:
            result_df = pd.concat([result_df, row_df], sort=False)
    return result_df

df = self.sort_hierachical(df, "category", "amount")

我的问题:是否有一种很好的高性能方法可以在 pandas 中完成这样的事情。某种分组排序或多索引技巧?

能够解决这个具有挑战性的问题的人将会获得好报:)

Edit:

这几乎有效...但是 -1000, 1000 搞乱了排序顺序。

def _sort_tree_df(self, df, tree_column, sort_column):
    sort_key = sort_column + '_abs'
    df[sort_key] = df[sort_column].abs()
    df.index = pd.MultiIndex.from_frame(df[tree_column].str.split(":").apply(lambda x: [y.strip() for y in x]).apply(pd.Series))
    sort_columns = [df[tree_column].values]
    sort_columns.append(df[sort_key].values)
    for x in range(df.index.nlevels, 0, -1):
        group_lvl = list(range(0, x))
        sort_columns.append(df.groupby(level=group_lvl)[sort_key].transform('max').values)
    sort_indexes = np.lexsort(sort_columns)
    df_sorted = df.iloc[sort_indexes[::-1]]
    df_sorted.reset_index(drop=True, inplace=True)
    df_sorted = df_sorted.drop(sort_key, axis=1)
    return df_sorted

Edit2:

好吧,我想我已经成功了。我仍然很困惑 lexsort 是如何工作的。我通过受过教育的反复试验完成了这项工作。如果你明白的话请随时解释一下。也欢迎发布更好的方法。

def _sort_tree_df(self, df, tree_column, sort_column, delimeter=':'):
    df.index = pd.MultiIndex.from_frame(df[tree_column].str.split(delimeter).apply(lambda x: [y.strip() for y in x]).apply(pd.Series))
    sort_columns = [df[tree_column].values]
    sort_columns.append(df[sort_column].abs().values)
    for x in range(df.index.nlevels, 0, -1):
        group_lvl = list(range(0, x))
        sort_columns.append(df.groupby(level=group_lvl)[sort_column].transform('sum').abs().values)
    sort_indexes = np.lexsort(sort_columns)
    df_sorted = df.iloc[sort_indexes[::-1]]
    df_sorted.reset_index(drop=True, inplace=True)
    return df_sorted

Edit3: 实际上这并不总是正确排序:(

Edit4问题是我需要一种方法来使变换('sum')仅适用于 level = x-1 的项目

即类似:

df['level'] = df[tree_column].str.count(':')

sorting_by = df.groupby(level=group_lvl)[sort_column].transform('sum' if 'level' = x-1).abs().values

or

sorting_by = df.groupby(level=group_lvl).loc['level' = x-1: sort_column].transform('sum').abs().values

两者均无效

有人知道如何在多索引 df 上进行这样的条件转换吗?


我不确定我是否完全理解这个问题,但我认为您应该将列拆分为子类别,然后根据您想要的层次结构进行值排序。像下面这样的东西可能会完成这项工作。

使用以下命令创建新列:

for _, row in df.iterrows():
    for item, col in zip(row.category.split(':'), ['cat', 'sub_cat', 'sub_sub_cat']):
        df.loc[_, col] = item

然后对它们进行排序

df.sort_values(['cat', 'sub_cat', 'sub_sub_cat', 'amount'])

category    amount  cat     sub_cat     sub_sub_cat
3   Household   1100    Household   NaN     NaN
7   Household : Cleaning    100     Household   Cleaning    NaN
8   Household : Cleaning : Bathroom     75  Household   Cleaning    Bathroom
9   Household : Cleaning : Kitchen  25  Household   Cleaning    Kitchen
10  Household : Rent    400     Household   Rent    NaN
4   Household : Utilities   600     Household   Utilities   NaN
6   Household : Utilities : Electric    200     Household   Utilities   Electric
5   Household : Utilities : Water   400     Household   Utilities   Water
11  Living  250     Living  NaN     NaN
15  Living : Anitsomething  -1000   Living  Anitsomething   NaN
13  Living : Food   100     Living  Food    NaN
12  Living : Other  150     Living  Other   NaN
14  Living : Something  1000    Living  Something   NaN
0   Transport   5000    Transport   NaN     NaN
1   Transport : Car     4900    Transport   Car     NaN
2   Transport : Train   100     Transport   Train   Na
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何按分层类别结构中的值对 pandas 中的数据框进行排序 的相关文章

随机推荐

  • 捕获 CommandOnCooldown 错误

    我正在制作一个有冷却时间的不和谐机器人 并且我正在尝试制作一个事件 当CommandOnCooldown发生错误时 机器人会通过私信告诉他们需要等待多长时间 这是我的代码 看起来一切正常 但它不知道 retry after 意味着什么 bo
  • 在 matplotlib 中添加新的导航模式

    我正在编写一个 wx matplotlib 应用程序 并且在向 matplotlib 导航工具栏添加新工具时遇到相当大的困难 基本上我想添加选择工具 选取框 套索等 以切换受控子图的鼠标模式 到目前为止 我还没有找到任何功能可以让我轻松地做
  • 在 python 中将数组作为参数传递

    我是Python新手 现在我需要声明大小为 20 的数组并将该数组传递给函数 需要数组的函数如下 function args The args是一个输入function 谁能帮我 如何在 python 中传递数组 当你说 数组 时 我假设你
  • 如何在不更改设置的情况下不区分大小写排序

    我的索引名称是 data new 下面是插入索引的代码 test id 1 name A professor Bill Cage accounting id 2 name AB professor Gregg Payne engineeri
  • 使用 GitHub 时防止将大文本文件添加到提交

    我们想要防止 非常大的文本文件 每个文件 gt 50MB 被提交到git代替git lfs 因为它们夸大了 git 历史 问题是 其中 99 大小差异的原因 这些是 YAML 文件 它们支持通过 Base64 编码进行二进制序列化 我们无法
  • 在基于 AngularJS 的 Web 应用程序中使用 Selenium

    我逐渐知道 Selenium 是 UI 测试之父 现在我的问题是为什么 Angular 团队开发了 Protractor 对于基于 AngularJS 的 Web 应用程序 Selenium 不能完成同样的工作 Protractor 所做的
  • iOS 中的自动旋转崩溃

    当我更改设备方向时 我正在使用的应用程序出现异常终止 崩溃 我无法经常重现它 当我旋转时 它并不总是发生 假设机会约为 0 01 但这是一个严重的问题 我附上崩溃报告的重要部分 Exception Type EXC BAD ACCESS S
  • while 循环无法访问代码

    当我编译这段代码时 public static void main String args int x 0 while false System out println hello 它显示编译时错误无法访问代码 但是当我将这段代码修改为 p
  • 枚举字段的自定义排序顺序

    是否可以将 JPA 中的字母排序更改为自定义排序 我在列中有这些数据division BRONZE SILVER GOLD DIAMOND 我已将其映射到实体字段 public enum Division BRONZE SILVER GOL
  • Kubernetes 集群自动缩放器似乎不适用于 GKE?

    我定义了一个节点池 最小实例设置为 1 最大实例设置为 5 并启用了自动缩放 但它似乎并没有缩小规模 我已经封锁了一个节点 已经过去12个多小时了 没有待处理的 Pod 删除节点不会减少我自己的部署的副本数量 相关节点上运行以下 pod f
  • Three.js 对象的“中心”是什么?

    当我使用 Blender 对对象进行建模时 我能够明确定义其发生平移和旋转的中心位置 当使用 Three js 对象时 我似乎没有找到等效的对象 Three js 对象是否具有定义其 中心 位置的属性 如果不是 物体的中心是如何确定的 在
  • NestJs:如何使 Body 输入形状与实体的 DTO 不同?

    我的照片和标签对象有 DTO 如下所示 export class PhotoDto readonly title string readonly file string readonly tags TagDto export class T
  • Qt 信号槽,新符号中的转换类型[重复]

    这个问题在这里已经有答案了 鉴于以下两个 connect ui gt comboBox SIGNAL activated QString ps SLOT requestPlotsAvailable QString connect ui gt
  • 如何在 QTableWidget 的行和列中自动换行文本?

    I tried QTableWidget j new QTableWidget 10000 5 centralWidget j gt setColumnWidth 0 500 j gt setColumnWidth 1 30 j gt se
  • Laravel 模型、构建器和集合之间的区别

    我在 Laravel 文档上发现了这个代码片段 Retrieve a model by its primary key flight App Flight find 1 Retrieve the first model matching t
  • gradle 构建工具版本从 1.2.3 升级到 1.3.1 的问题

    我已将 gradle 构建工具从 1 2 3 升级到 1 3 1 并开始在 gradle 同步上看到以下错误 我使用 1 2 3 版本没有任何问题 我使用的是 gradleVersion 2 3 无论如何我可以避免这个错误吗 错误 您的项目
  • 是否可以使用 Google BERT 来计算两个文本文档之间的相似度?

    是否可以使用 Google BERT 来计算两个文本文档之间的相似度 据我了解 BERT 的输入应该是有限大小的句子 一些作品使用 BERT 来计算句子的相似度 例如 https github com AndriyMulyar semant
  • 具有内部赋值延迟的阻塞和非阻塞语句之间的区别

    以下 2 个 verilog 代码片段有什么区别 1 always in out 5 in AND 2 always in out lt 5 in 考虑到always块中不存在其他行 输出会有什么不同吗 问题参考幻灯片 16 参见 o5 和
  • ThemeInfo 属性有什么用?

    每当我创建新的 WPF 应用程序或 WPF 用户控件库时 AssemblyInfo cs文件包含以下属性 assembly ThemeInfo ResourceDictionaryLocation None where theme spec
  • 如何按分层类别结构中的值对 pandas 中的数据框进行排序

    我有一个 pandas 数据框 pd DataFrame category Transport Transport Car Transport Train Household Household Utilities Household Ut