首页 > 编程问答 >Pandas 有效地获取每个数据帧组中具有多个 n 值的前 n 行

Pandas 有效地获取每个数据帧组中具有多个 n 值的前 n 行

时间:2024-08-04 16:50:12浏览次数:14  
标签:python pandas dataframe machine-learning data-science

从像

df = pd.DataFrame(
    [
        {'name': 'a', 'id': 0, 'category': '1'},
        {'name': 'b', 'id': 1, 'category': '1'},
        {'name': 'c', 'id': 2, 'category': '1'},
        {'name': 'd', 'id': 3, 'category': '1'},
        {'name': 'e', 'id': 4, 'category': '2'},
        {'name': 'f', 'id': 5, 'category': '2'},
        {'name': 'g', 'id': 6, 'category': '2'},
        {'name': 'h', 'id': 7, 'category': '3'},
        {'name': 'i', 'id': 8, 'category': '3'},
        {'name': 'j', 'id': 9, 'category': '3'},
    ]
)

  name  id category
0    a   0        1
1    b   1        1
2    c   2        1
3    d   3        1
4    e   4        2
5    f   5        2
6    g   6        2
7    h   7        3
8    i   8        3
9    j   9        3

这样的数据帧开始,我想提取每个类别的第一 n 行,每个类别都有不同的 n 如果 n 对于所有类别都是相同的,那么 这个问题的解决方案 将会很好而且快速:

df_head = df.groupby(by=['category'], as_index=False, sort=False).head(2)

给出

  name  id category
0    a   0        1
1    b   1        1
4    e   4        2
5    f   5        2
7    h   7        3
8    i   8        3

但是如果我想要不同的 n ,我就只剩下像 this

num_grabs = {'1': 3, '2': 1, '3': 2}
df_apply = df.groupby(
    by=['category'],
    as_index=False,
    sort=False
).apply(
    lambda x: x.head(num_grabs[x.loc[x.index[0], 'category']])
).reset_index(drop=True)

这样的方法可以正确给出

  name  id category
0    a   0        1
1    b   1        1
2    c   2        1
3    e   4        2
4    h   7        3
5    i   8        3

但是,即使对于中等大小的数据来说,这也非常慢。有没有更有效的方法来解决多 n 问题?


虽然给出的 apply 方法有效,但它对于大型数据集来说效率可能很低,因为它循环遍历每个组。以下是一种可能更快的替代方法,它使用 NumPy 和一些聪明的索引:

import pandas as pd
import numpy as np

def get_top_n_per_group(df, group_col, n_dict):
    # 获取组大小和累积计数
    group_sizes = df[group_col].value_counts(sort=False).to_numpy()
    group_cumsum = np.cumsum(group_sizes)

    # 创建一个布尔掩码,指示要保留的行
    n_values = np.array([n_dict[key] for key in sorted(n_dict)])
    max_n = n_values.max()
    row_indices = np.arange(len(df))
    group_starts = np.concatenate(([0], group_cumsum[:-1]))
    within_group_indices = row_indices - group_starts.repeat(group_sizes)
    mask = within_group_indices < n_values.repeat(group_sizes)

    # 应用掩码并返回过滤后的 DataFrame
    return df[mask]

# 示例用法
df = pd.DataFrame({
    'name': 'a b c d e f g h i j'.split(),
    'id': range(10),
    'category': '1 1 1 1 2 2 2 3 3 3'.split()
})

num_grabs = {'1': 3, '2': 1, '3': 2}
df_head = get_top_n_per_group(df, 'category', num_grabs)
print(df_head)

这段代码的工作原理如下:

  1. 计算组大小和累积计数: 这有助于我们稍后确定每组的起始位置。
  2. 创建布尔掩码:
  3. 我们创建一个 row_indices 数组来表示 DataFrame 中的每一行。
  4. group_starts 数组存储每组的起始索引。
  5. within_group_indices 计算每行相对于其组的起始位置。
  6. 最后, mask 通过检查 within_group_indices 是否小于每组所需的 n 值来标识要保留的行。
  7. 应用掩码并返回过滤后的 DataFrame: 我们简单地将掩码应用于原始 DataFrame 以获取所需的输出。

此方法避免了显式循环,并且应该比基于 apply 的方法快得多,尤其是在大型数据集上。

此解决方案假定“类别”列已排序,或者至少每组的顺序不影响结果。如果的数据集中“类别”列的值的顺序不同,则需要对数据进行排序或调整解决方案以首先收集类别值。

标签:python,pandas,dataframe,machine-learning,data-science
From: 78830630

相关文章

  • 16:Python一些常用的变量命名
    变量名的命名直接影响到程序的易读性,好的变量名应该简洁、易于理解。一、单字符变量名数学中通常用x,y来表示坐标,同样的,在命名变量时,可以使用一些具有特定含义的单个字符。这样的变量名兼具有意义和极简两大优点,作为编程人员应熟记。具体列举如下。i、j、k:数值(integer(整数))......
  • 15:Python数据类型的综合对比整理
    #Python有六个标准的数据类型:#Numbers(数字)int#String(字符串)str字符串一旦创建,不可修改,一旦修改或者拼接,都会造成重新生成字符串#List(列表)list中号括起来,逗号分开,可以是数字、字符串、列表、布尔值,列表可以嵌套任何类型,列表有序元素可以被修改#Tup......
  • 用Python打造精彩动画与视频, 6.2 使用Manim进行数学和科学可视化
     6.2使用Manim进行数学和科学可视化Manim(MathematicalAnimationEngine)是一款强大的动画制作工具,尤其适用于数学和科学领域的可视化。它由3Blue1Brown的GrantSanderson开发,旨在通过动画演示复杂的数学概念,使其更易于理解。使用Manim,用户可以创建高质量的数学动画,从简单的......
  • 用Python打造精彩动画与视频,5.3 使用Manim创建简单动画
     5.3使用Manim创建简单动画在这一节中,我们将介绍如何使用Manim创建简单的动画。我们将从基本的场景构建开始,然后演示如何添加动画效果。通过这些示例,你将能够掌握使用Manim创建各种动画的基本技能。5.3.1创建一个简单的场景Manim中的基本单元是场景(Scene)。每个场景都是一......
  • 用Python打造精彩动画与视频, 5.2 安装和设置Manim
     5.2安装和设置ManimManim是一个强大的动画库,用于创建高质量的数学动画。它最初由3Blue1Brown的GrantSanderson开发,并被广泛用于教育和展示。以下是安装和设置Manim的详细步骤。5.2.1安装ManimManim需要Python环境和一些依赖库。在安装Manim之前,请确保已经......
  • 用Python打造精彩动画与视频,6.1 复杂动画场景的构建
     第六章:探索Manim的潜力6.1复杂动画场景的构建在本节中,我们将深入探索如何使用Manim构建复杂的动画场景。Manim是一款功能强大的Python库,广泛应用于数学可视化和教育视频制作。通过理解并掌握Manim的高级功能和技巧,你将能够创建出引人入胜且具有高可读性的动画场景。6.1.1......
  • 在 Python 中从 HTML 中抓取嵌入的 Google Sheet
    这对我来说相对棘手。我正在尝试提取来自python中的google工作表的嵌入表。这是链接我不拥有该工作表,但它是公开可用的。这是迄今为止我的代码,当我输出标题时,它向我显示“”。任何帮助将不胜感激。最终目标是将此表转换为pandasDF。多谢你们importlx......
  • 如何使用 Python 在 Google 或 DuckDuckGo 中快速获取答案
    我有一个人工智能助手项目,我希望它在互联网上搜索。我想使用适用于Python的GoogleQuickAnswerBox或DuckDuckGoInstantAnswerAPI。我看到了其他问题,但它们对我没有多大帮助。这是我想要实现的一个示例:问题:什么是长颈鹿?Google的答案:DuckDuckGo的......
  • 如何为可以在递归调用中重新分配的 python 函数制定类型提示?
    采取以下最小示例:S=TypeVar("S",bound=int|str)defmeth(a:S)->S:ifa=="5":returnstr(meth(int(a)))returna特别是,上面的方法可以采用字符串或整数。它总是返回与其输入相同类型的值,但它可以递归地调用自身,在这种情况下,S的值......
  • 使用 python 和 json 抓取该网站的正确 URL 是什么?
    试图抓取这个网站-->https://ucr.gov/enforcement/1000511它曾经使用下面的代码,然后停止了。无法获取响应中的json或任何内容。query="1000511"url='https://ucr.gov/api/enforcement/{}'.format(query)headers={'User-Agent':'Mozilla/5.0(......