2016-11-17 3 views
2

Я работаю с большим колонке dataframe, которые имеют следующую структуру:Как создать уникальный столбец идентификатора с заданной числовой серией?

В:

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

Out:

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 до п. Это указывает порядок в моих данных. Например:

A 
2 0 
3 1 
4 2 
5 0 

Давайте возьмем кусок df1 (от индекса 2 к 5), в колонке A0 представляет собой начало и 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 

Я добавил диаграмму, чтобы быть более ясными ,

ответ

5

Я думаю, что вы можете использовать:

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 

Более общие с работы с NaN после diff:

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 
+0

Святое дерьмо ... Я использовал iter(), next и if loops .... это потрясающе. Можете ли вы дать объяснение? ... –

+1

ya, дайте мне секунду – jezrael

+0

Большое спасибо –