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

我有以下数据,End1、End2 处的值按顺序出现,我想要另一列来确定它在 End1 处出现的顺序。End2 处的值有可能永远不会到达 End1 处,但如果它出现在任何地方,都会对下一项的顺序产生影响。


ID   End1   End2  

1    A      B      

1    A      B      

1    B      A     

1    A      B

1    C      B

1    C      D

1    D      C

1    C      D

1    D      C

2    A      B

2    A      B

2    A      C

2    A      C

2    C      A

2    C      A

2    D      C

2    C      D

2    D      C

我想要有以下输出:


ID   End1   End2  Order

1    A      B      1

1    A      B      1

1    B      A      2     

1    A      B      1

1    C      B      3 

1    C      D      3

1    D      C      4

1    C      D      3

1    D      C      4

2    A      B      1

2    A      B      1

2    A      C      1

2    A      C      1 

2    C      A      3

2    C      A      3

2    D      C      4

2    C      D      3

2    D      C      4

我尝试了不同的函数,但它们都在计算该值的出现次数。任何帮助表示赞赏。

更新:这里还有另外两个要求:


每个组的顺序都会重置。虽然 A 在 ID=1 时可能具有阶数 1,但对于任何其他 ID,它可能具有阶数 2。

一些建议的解决方案没有考虑到 End2 处的项目(对于 ID=2 中的 B)可能永远不会到达 End1。但它会影响其后的项目的顺序。

为了更清楚地说明 ID=3 在同一数据集中可能有以下数据:


ID End1 End2

2  D    C  

.....  

3  B    E 

3  E    B

3  E    B

3  G    B

3  C    B

所需的输出是


ID End1 End2 Order

2  D    C    4 

.....  

3  B    E    1

3  E    B    2

3  E    B    2 

3  G    B    3

3  C    B    4


梦里花落0921
浏览 98回答 3
3回答

凤凰求蛊

将索引设置为ID并使用DataFrame.stack来重塑框架,然后使用Series.factorize创建一个标识不同值的数字数组,从而创建一个系列s,然后使用Series.groupbyons和agg使用first(因为我们必须首先优先考虑列的顺序End1)End2: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  Order0    1    A    B      11    1    A    B      12    1    B    A      23    1    A    B      14    1    C    B      35    1    C    D      36    1    D    C      47    1    C    D      38    1    D    C      49    2    A    B      110   2    A    B      111   2    A    C      112   2    A    C      113   2    C    A      314   2    C    A      315   2    D    C      416   2    C    D      317   2    D    C      4

LEATH

import pandas as pddf = 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'] = orderdf.Order = df.Order.astype(int)    def f(g):    sequence = pd.unique(g.stack())    order = (g.End1.to_numpy() == sequence[:,None]).argmax(0) + 1    return ordergb = df.groupby('ID')orders = gb.apply(f)df.loc[orders.index,'foo'] = np.concatenate(orders.values)

江户川乱折腾

一种可能的方法是连接 End1+End2 中的字符串值,并将结果用作字典的键。该算法看起来像:counter = 1new_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
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python