Изменение значений строк на основе предыдущих значений строк

#python #pandas

Вопрос:

У меня есть фрейм данных, который выглядит так:

 Province Admissions Eastern Cape 10 Private 3 Public 7 Free State 20 Private 15  Public 5   

Я хочу изменить «Частное» и «Публичное», чтобы ссылаться на провинцию. Я хочу получить следующий кадр данных:

 Province Admissions Eastern Cape 10 Eastern Cape-Private 3 Eastern Cape-Public 7 Free State 20 Free State-Private 15  Free State-Public 5  

На самом деле я уже достиг этого с помощью следующего кода:

 for row in range(0,len(df)):  df['Province'] = np.where((df['Province'] == 'Private'), df['Province'].shift(1) ' '  df['Province'], df['Province'])  df['Province'] = np.where((df['Province'] == 'Public'), df['Province'].shift(2) ' '  df['Province'], df['Province'])  

Однако я хотел бы сделать это в более общем подходе, в случае, если порядок частного и публичного поменяется местами. Прямо сейчас Частное важнее публичного, поэтому мой метод работает. Буду признателен за любой вклад!

Комментарии:

1. возможно, немного более общим решением было бы, когда у вас есть «публичный» или «частный», затем выполните .shift(1) , а если это «публичный» или «частный», сделайте .shift(2) что-нибудь еще, просто сохраните .shift(1) .

2. Всегда ли это тройка (Place, Private, Public) (или частное и публичное меняются местами)?

3. хммм, ты пробовал это на сводном столе? кажется, что в сводной таблице все намного чище.

4. Первый вопрос, который я бы задал, — почему for row in range(0,len(df)): ? Кроме этого, ваши два np.where варианта отлично подойдут для вашего варианта использования.

Ответ №1:

Вы можете сделать mask и ffill создать добавляющий массив

 s = df.Province.mask(df.Province.isin(['Private','Public'])).ffill() df['Province'] = np.where(df.Province.isin(['Private','Public']), s   ' '   df.Province, df.Province)  

Комментарии:

1. Я собирался использовать тот же подход, за исключением того, что я кэширую df.Province.isin .