【问题标题】:Ranking on multiple columns and labeling ties between obsersations in pandas对多列进行排名并标记熊猫观察之间的联系
【发布时间】:2019-01-31 21:03:41
【问题描述】:

我有一个像这样的df:

   group name    sum count      max_size
 1     1 aaa       3     2            4
 2     1 bbb       3     1            4
 3     1 ccc       2     2            4
 4     1 ddd       2     2            4
 5     1 eee       1     0            4
 6     2 aaa       3     2            3
 7     2 bbb       3     1            3
 8     2 ccc       2     3            3
 9     2 ddd       2     1            3
10     3 aaa       3     4            4
11     3 bbb       3     2            4
12     3 ccc       2     5            4
13     3 ddd       2     1            4
14     3 eee       2     1            4
15     3 fff       2     1            4

我想根据这个决策推理来标记每个观察:

  • 首先按组 groupby(),然后按 sum 排列名称,然后按 count 降序排列
  • 选择前n个元素,如max_size,这是组内要选择的最大元素数

在像group 2 这样的情况下,要选择的元素的最大大小 (3) 和 3 个明确的候选者。

  group name  decision       sum count     max_size
1     2 aaa   winner           3     2            3
2     2 bbb   winner           3     1            3
3     2 ccc   winner           2     3            3
4     2 ddd   loser            2     1            3

aaabbbccc 是前 3 名,首先是 sum,然后是 count,而 ddd 出局了。

对于group 3

  group name  decision          sum count     max_size
1     3 aaa   winner              3     4            4
2     3 bbb   winner              3     2            4
3     3 ccc   winner              2     5            4
4     3 ddd   unclear             2     1            4
5     3 eee   unclear             2     1            4
6     3 fff   unclear             2     1            4

aaabbbccc 是前 3 个元素,但第 4 个元素(假设 max_size = 4)尚不清楚。 dddeeefff 具有相同的计数和相同的总和。

我想达到一个最终的数据框,像这样标记观察结果:

   name  decision   sum count max_size
 1 aaa   winner       3     2        4
 2 bbb   winner       3     1        4
 3 ccc   unclear      2     2        4
 4 ddd   unclear      2     2        4
 5 eee   winner       1     0        4
 6 aaa   winner       3     2        3
 7 bbb   winner       3     1        3
 8 ccc   winner       2     3        3
 9 ddd   loser        2     1        3
10 aaa   winner       3     4        4
11 bbb   winner       3     2        4
12 ccc   winner       2     5        4
13 ddd   unclear      2     1        4
14 eee   unclear      2     1        4
15 fff   unclear      2     1        4

可重现的例子:

{'group': {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 2, 6: 2, 7: 2, 8: 2, 9: 3, 10: 3, 11: 3, 12: 3, 13: 3, 14: 3}, 'name': {0: 'aaa', 1: 'bbb', 2: 'ccc', 3: 'ddd', 4: 'eee', 5: 'aaa', 6: 'bbb', 7: 'ccc', 8: 'ddd', 9: 'aaa', 10: 'bbb', 11: 'ccc', 12: 'ddd', 13: 'eee', 14: 'fff'}, 'decision': {0: 'winner', 1: 'winner', 2: 'unclear', 3: 'unclear', 4: 'winner', 5: 'winner', 6: 'winner', 7: 'winner', 8: 'loser', 9: 'winner', 10: 'winner', 11: 'winner', 12: 'unclear', 13: 'unclear', 14: 'unclear'}, 'sum': {0: 3, 1: 3, 2: 2, 3: 2, 4: 1, 5: 3, 6: 3, 7: 2, 8: 2, 9: 3, 10: 3, 11: 2, 12: 2, 13: 2, 14: 2}, 'count': {0: 2, 1: 1, 2: 2, 3: 2, 4: 0, 5: 2, 6: 1, 7: 3, 8: 1, 9: 4, 10: 2, 11: 5, 12: 1, 13: 1, 14: 1}, 'max_size': {0: 4, 1: 4, 2: 4, 3: 4, 4: 4, 5: 3, 6: 3, 7: 3, 8: 3, 9: 4, 10: 4, 11: 4, 12: 4, 13: 4, 14: 4}}

【问题讨论】:

  • 让我们选择第 1 组,我有 5 个元素,我必须选择 4 个(max_elements 值)。我首先用总和对它们进行排名,然后是优先级。 aaa 和 bbb 是前 2 个。 ccc 和 ddd 的总和计数值相同 - 我只选择两者中的一个,但将它们标记为“pick_random”,然后 eee 是最后一个被选择的值:最终大小该组将是 4。
  • 我认为根据您的逻辑,您对第一组的输出不正确。有 4 个赢家 aaa、bbb、ccc 和 ddd 是明显的赢家,而 eee 是明显的输家不是吗?
  • 您只需要选择一个不确定的获胜者。 @ALollz
  • 您需要提供输入 DataFrame 作为可以复制并粘贴到 Python 中的内容(就像您对输出所做的那样)。

标签: python pandas


【解决方案1】:

您也许可以缩短以下代码,但它应该可以工作:

# sort values
df = df.sort_values(['group', 'sum', 'count'], ascending=[True, False, False])

# duplicated performance columns are candidates for unclear
df['dup'] = df.duplicated(['group', 'sum', 'count'], False)

# set decision column
df['decision'] = 'winner'
# if dup, those are unclear
df.loc[df.dup == True, 'decision'] = 'unclear'

# allocate just a fraction of weight for unclear entries
df['alloc'] = df.loc[df.dup == True].groupby(['group']).decision.transform(lambda x: 1/np.size(x)+1e-6)
# if not dup, then allocate 1
df.loc[df.dup == False, 'alloc'] = 1

# cumulative allocation should add up to compare with max_size
df['cum_alloc'] = df.groupby('group').alloc.cumsum().astype(int)
# decide loser with clear logic
df.loc[df.cum_alloc > df.max_size, 'decision'] = 'loser'

# finally trim columns
df = df[['name', 'decision', 'sum', 'count', 'max_size']]

输出:

>>> df
   name decision  sum  count  max_size
1   aaa   winner    3      2         4
2   bbb   winner    3      1         4
3   ccc  unclear    2      2         4
4   ddd  unclear    2      2         4
5   eee   winner    1      0         4
6   aaa   winner    3      2         3
7   bbb   winner    3      1         3
8   ccc   winner    2      3         3
9   ddd    loser    2      1         3
10  aaa   winner    3      4         4
11  bbb   winner    3      2         4
12  ccc   winner    2      5         4
13  ddd  unclear    2      1         4
14  eee  unclear    2      1         4
15  fff  unclear    2      1         4

【讨论】:

    猜你喜欢
    • 2012-08-21
    • 1970-01-01
    • 2013-10-09
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 2017-06-17
    • 1970-01-01
    相关资源
    最近更新 更多