Как создать идентификатор, который увеличивается на основе нескольких условий? - PullRequest
2 голосов
/ 29 апреля 2020

Мне нужно создать идентификатор, который увеличивается на единицу в соответствии с некоторыми указанными c условиями:

  1. RespondentID в строке выше не совпадает с RespondentID в этой строке
  2. Когда в последней строке была цель == 1
  3. Когда в последней строке была цель == 7 AND TripNumber == 1

Если применимо более одного из этих условий, оно все равно должно быть только увеличить на 1.

data = {'RespondentID': [101, 101, 101, 101, 102, 102, 102, 103, 103, 103, 106, 106, 106, 107, 108, 108, 109, 109, 109, 109, 109, 110], 
        'TripNumber':   [1, 2, 3, 4, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 2, 1, 2, 3, 4, 5, 1], 
        'Purpose':      [4, 1, 6, 1, 7, 4, 1, 4, 6, 8, 6, 5, 1, 7, 4, 4, 7, 5, 6, 5, 1, 4]} 

df = pd.DataFrame(data=data)

И мне нужно создать

df['JourneyID'] = [1, 1, 2, 2, 3, 4, 4, 5, 5, 5, 6, 6, 6, 7, 8, 8, 9, 10, 10, 10, 10, 11] 

Чтобы разбить его.

  • 1: новый (первый) RespondentID.

  • 2: последний ряд имел 1 в Назначении.

  • 3, 5, 7 и 11: новый RespondentID (и последняя строка имела 1 в Назначении).

  • 4 и 10: в последней строке было 7 по назначению И TripNumber был равен 1.

  • 6 и 9: новый RespondentID

  • 8: новый RespondentID (и последняя строка имела 7 в Purpose, а TripNumber был 1)

Это решение хорошо работало для условия 2:

temp = ((df['purpose']==1).cumsum()+1).shift(1) 
#Makes it go up by one each time the previous row had purpose == 1
temp[0]=1
df['JourneyID'] = temp

но мне также нужно увеличить его на одно с двумя другими условиями.

1 Ответ

3 голосов
/ 29 апреля 2020

Создать серию True / False, которая проверяет, является ли любой из этих условий истинным. Тогда cumsum той серии. Использование .shift позволяет нам проверять условия в предыдущих строках. .fillna(False) фиксирует первую строку, когда мы shift получаем NaN 'd.

Поскольку df['RespondentID'].ne(df['RespondentID'].shift()) всегда возвращает True для первой строки, гарантируется, что отсчет начинается с 1

s = (
    df['RespondentID'].ne(df['RespondentID'].shift())                # Condition 1
    | df.Purpose.eq(1).shift().fillna(False)                         # Condition 2
    | (df.Purpose.eq(7) & df.TripNumber.eq(1)).shift().fillna(False) # Condition 3
    )

df['JourneyID'] = s.cumsum()
...