【问题标题】:How to create a unique id column given an ordered numerical series?如何在给定有序数字系列的情况下创建唯一的 id 列?
【发布时间】:2016-11-17 08:05:32
【问题描述】:

我正在使用具有以下结构的大型数据框列:

在:

df1 = pd.DataFrame({'A': [0,0,0,1,2,0,1,0,1,2,3,4,5,6,7]})

输出:

    A
0   0
1   0
2   0
3   1
4   2
5   0
6   1
7   0
8   1
9   2
10  3
11  4
12  5
13  6
14  7

如您所见,A 是一个从 0 到 n 的有序序列。这代表了我数据中的一个顺序。例如:

    A
2   0
3   1
4   2
5   0

让我们取一大块df1(从索引25),在A 列中,0 代表序列的开始,2 代表序列的结束。另一方面,如果没有连续的数字(例如0),则表示该序列结束。因此,我的问题是如何有效地生成一个新列(例如id),该列由基于A 数字顺序的唯一键或数字一致

      A                             id
0     0 ->  begin and ends          1                

1     0 ->  begin and ends          2

2     0 ->  begin                   3
3     1 ->  continue                3
4     2 ->  ends                    3

5     0 ->  begin                   4
6     1 ->  ends                    4

7     0 ->  begin                   5
8     1 ->  continue                5
9     2 ->  continue                5
10    3 ->  continue                5
11    4 ->  continue                5
12    5 ->  continue                5
13    6 ->  continue                5
14    7 ->  ends                    5

为了更清楚,我添加了一个图表。

【问题讨论】:

    标签: python pandas numpy data-structures itertools


    【解决方案1】:

    我认为你可以使用:

    print ((df1.A.diff() < 1).cumsum() + 1)
    0     1
    1     2
    2     3
    3     3
    4     3
    5     4
    6     4
    7     5
    8     5
    9     5
    10    5
    11    5
    12    5
    13    5
    14    5
    Name: A, dtype: int32
    

    diff 之后处理NaN 更一般:

    dif = df1.A.diff()
    dif.iloc[0] = df1.loc[0,'A']
    print ((dif < 1).cumsum())
    0     1
    1     2
    2     3
    3     3
    4     3
    5     4
    6     4
    7     5
    8     5
    9     5
    10    5
    11    5
    12    5
    13    5
    14    5
    Name: A, dtype: int32
    

    解释:

    首先通过diff找到差异:

    dif = df1.A.diff()
    print (dif)
    0     NaN
    1     0.0
    2     0.0
    3     1.0
    4     1.0
    5    -2.0
    6     1.0
    7    -1.0
    8     1.0
    9     1.0
    10    1.0
    11    1.0
    12    1.0
    13    1.0
    14    1.0
    Name: A, dtype: float64
    

    然后将第一个值 (NaN) 设置为原始值:

    dif.iloc[0] = df1.loc[0,'A']
    

    获取掩码:

    print (dif < 1)
    0      True
    1      True
    2      True
    3     False
    4     False
    5      True
    6     False
    7      True
    8     False
    9     False
    10    False
    11    False
    12    False
    13    False
    14    False
    Name: A, dtype: bool
    

    最后使用 cumsum 和布尔掩码:

    print ((dif < 1).cumsum())
    0     1
    1     2
    2     3
    3     3
    4     3
    5     4
    6     4
    7     5
    8     5
    9     5
    10    5
    11    5
    12    5
    13    5
    14    5
    Name: A, dtype: int32
    

    【讨论】:

    • 天哪...我在使用 iter()、next 和 if 循环....太棒了。你能解释一下吗?...
    • 是的,等一下
    • 非常感谢
    • 您似乎将diffindex 一起使用,但它不起作用-您使用类似df.index.diff() 的东西吗?
    • Super, select by [] 更安全,但使用 . - > df['A']df.A ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-04
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    相关资源
    最近更新 更多