为了账号安全,请及时绑定邮箱和手机立即绑定

如何为每个组的列中的顺序分配一个值基础?

如何为每个组的列中的顺序分配一个值基础?

梦里花落0921 2023-07-18 17:48:54
我有以下数据,End1、End2 处的值按顺序出现,我想要另一列来确定它在 End1 处出现的顺序。End2 处的值有可能永远不会到达 End1 处,但如果它出现在任何地方,都会对下一项的顺序产生影响。ID   End1   End2  1    A      B      1    A      B      1    B      A     1    A      B1    C      B1    C      D1    D      C1    C      D1    D      C2    A      B2    A      B2    A      C2    A      C2    C      A2    C      A2    D      C2    C      D2    D      C我想要有以下输出:ID   End1   End2  Order1    A      B      11    A      B      11    B      A      2     1    A      B      11    C      B      3 1    C      D      31    D      C      41    C      D      31    D      C      42    A      B      12    A      B      12    A      C      12    A      C      1 2    C      A      32    C      A      32    D      C      42    C      D      32    D      C      4我尝试了不同的函数,但它们都在计算该值的出现次数。任何帮助表示赞赏。更新:这里还有另外两个要求:每个组的顺序都会重置。虽然 A 在 ID=1 时可能具有阶数 1,但对于任何其他 ID,它可能具有阶数 2。一些建议的解决方案没有考虑到 End2 处的项目(对于 ID=2 中的 B)可能永远不会到达 End1。但它会影响其后的项目的顺序。为了更清楚地说明 ID=3 在同一数据集中可能有以下数据:ID End1 End22  D    C  .....  3  B    E 3  E    B3  E    B3  G    B3  C    B所需的输出是ID End1 End2 Order2  D    C    4 .....  3  B    E    13  E    B    23  E    B    2 3  G    B    33  C    B    4
查看完整描述

3 回答

?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

将索引设置为ID并使用DataFrame.stack来重塑框架,然后使用Series.factorize创建一个标识不同值的数字数组,从而创建一个系列s,然后使用Series.groupbyons和agg使用first(因为我们必须首先优先考虑列的顺序End1End2


s = pd.Series(df.set_index('ID').stack().factorize()[0] + 1)

df['Order'] = s.groupby(s.index // 2).first()

编辑:如果我们需要考虑每组的不同值:


s = pd.Series(np.hstack([g.factorize()[0] + 1 for _, g in

                         df.set_index('ID').stack().groupby(level=0)]))

df['Order'] = s.groupby(s.index // 2).first()

结果:


    ID End1 End2  Order

0    1    A    B      1

1    1    A    B      1

2    1    B    A      2

3    1    A    B      1

4    1    C    B      3

5    1    C    D      3

6    1    D    C      4

7    1    C    D      3

8    1    D    C      4

9    2    A    B      1

10   2    A    B      1

11   2    A    C      1

12   2    A    C      1

13   2    C    A      3

14   2    C    A      3

15   2    D    C      4

16   2    C    D      3

17   2    D    C      4


查看完整回答
反对 回复 2023-07-18
?
LEATH

TA贡献1936条经验 获得超6个赞

import pandas as pd

df = pd.DataFrame({'ID': {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1, 8: 1, 9: 2, 10: 2, 11: 2, 12: 2, 13: 2, 14: 2, 15: 2, 16: 2, 17: 2},

                   'End1': {0: 'A', 1: 'A', 2: 'B', 3: 'A', 4: 'C', 5: 'C', 6: 'D', 7: 'C', 8: 'D', 9: 'A', 10: 'A', 11: 'A', 12: 'A', 13: 'C', 14: 'C', 15: 'D', 16: 'C', 17: 'D'},

                   'End2': {0: 'B', 1: 'B', 2: 'A', 3: 'B', 4: 'B', 5: 'D', 6: 'C', 7: 'D', 8: 'C', 9: 'B', 10: 'B', 11: 'C', 12: 'C', 13: 'A', 14: 'A', 15: 'C', 16: 'D', 17: 'C'}})

pandas.unique将给出出现的顺序。


sequence查找该列的每个值的索引End1。分组依据'ID'因此顺序是唯一的'ID'。堆叠每个组/数据帧可以使列变平['End1','End2']。


df = df.set_index('ID')

gb = df.groupby('ID')

for k,g in gb:

    sequence = pd.unique(g.stack())

    order = (g.End1.to_numpy() == sequence[:,None]).argmax(0) + 1        

    df.loc[k,'Order'] = order

df.Order = df.Order.astype(int)    

def f(g):

    sequence = pd.unique(g.stack())

    order = (g.End1.to_numpy() == sequence[:,None]).argmax(0) + 1

    return order

gb = df.groupby('ID')

orders = gb.apply(f)

df.loc[orders.index,'foo'] = np.concatenate(orders.values)


查看完整回答
反对 回复 2023-07-18
?
江户川乱折腾

TA贡献1851条经验 获得超5个赞

一种可能的方法是连接 End1+End2 中的字符串值,并将结果用作字典的键。该算法看起来像:


counter = 1

new_column = []

my_dict = dict()

for row in data:

  key_to_check = row[End1]+row[End2]

  if key_to_check in my_dict:

     new_column.append(my_dict[key_to_check])

  else:

     my_dict[key_to_check] = counter

     new_column.append(my_dict[key_to_check])

  counter += 1


## append new_column to the data


查看完整回答
反对 回复 2023-07-18
  • 3 回答
  • 0 关注
  • 131 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信