【问题标题】:Group and find all values that belong to n unique maximum values分组并查找属于 n 个唯一最大值的所有值
【发布时间】:2019-12-04 18:15:07
【问题描述】:

我的数据框:

data = {'Input':[133217,133217,133217,133217,133217,133217,132426,132426,132426,132426,132426,132426,132426,132426],
 'Font':[30,25,25,21,20,19,50,50,50,38,38,30,30,29]}

     Input  Font
0   133217    30
1   133217    25
2   133217    25
3   133217    21
4   133217    20
5   133217    19
6   132426    50
7   132426    50
8   132426    50
9   132426    38
10  132426    38
11  132426    30
12  132426    30
13  132426    29

我想创建一个仅包含 字体 中属于 3 个唯一最大值的值的新数据框。例如,输入 133217 的 3 个最大字体值为 30、25、21。

预期输出:

op_data = {'Input':[133217,133217,133217,133217,132426,132426,132426,132426,132426,132426,132426],
 'Font':[30,25,25,21,50,50,50,38,38,30,30]}

     Input  Font
0   133217    30
1   133217    25
2   133217    25
3   133217    21
4   132426    50
5   132426    50
6   132426    50
7   132426    38
8   132426    38
9   132426    30
10  132426    30

我用 pandas 的 groupby 试过这个:

df = pd.DataFrame(data)
df['order'] = df.groupby('Input').cumcount()+1

然后我考虑了 df['order'] 中的 1,2,3 值,但没有按计划进行。有什么替代方法吗?

【问题讨论】:

  • 您说您需要 3 个最高值,但您的预期输出第一组有 4 个值,第二组有 7 个值。
  • 猜猜,这是因为 25 出现了两次。因此,反过来提出问题:您是否需要像 13321725 这样的重复值?

标签: python pandas-groupby


【解决方案1】:

您可以找到每个组的唯一值,获取具有三个最大值的列表并选择此列表中的行:

df.groupby('Input')['Font'].\
apply(lambda x: x[x.isin(np.sort(x.unique())[-3:])]).\
reset_index(level=0)

输出:

     Input  Font
6   132426    50
7   132426    50
8   132426    50
9   132426    38
10  132426    38
11  132426    30
12  132426    30
0   133217    30
1   133217    25
2   133217    25
3   133217    21

【讨论】:

  • 我还有另外两列,如果这样做,我会丢失这些列。有什么办法不丢失其他列的值?
  • @DGS 我已经编辑了我的答案。你可以在最后的索引上合并。
【解决方案2】:

我会分两步完成任务。

第一个是订购数据框。您的数据框似乎已订购。

dft = dft.sort_values(by=['Input','Font'],ascending=False)

然后,使用 'Input' 列和 head(3) 进行分组,以获得每个不同的 'Input' 组的前 3 名:

dft = dft.groupby('Input').head(3)
print(dft)

    Input  Font
0  133217    30
1  133217    25
2  133217    25
6  132426    50
7  132426    50
8  132426    50

【讨论】:

    【解决方案3】:

    您也可以使用pandas.DataFrame.nlargest() 函数:

    df.drop_duplicates().groupby('Input').apply(lambda grp: grp.nlargest(3, 'Font'))
    
    # 132426 6   132426    50
    #        9   132426    38
    #        11  132426    30
    # 133217 0   133217    30
    #        1   133217    25
    #        3   133217    21
    

    请注意,任何 重复 值都会被删除,因此不会被考虑在内。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-19
      • 2012-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多