Python панды: Как изменить один столбец, который (сложно) основан на другом? - PullRequest
1 голос
/ 11 июня 2019

У меня есть данные бронирования, в то время как новая строка вставляется, когда клиент инициирует, изменяет, удаляет или повторно активирует заказ. «доставлено» показывает, был ли продукт фактически доставлен, что обычно происходит, если заказ не был удален в последнем обновлении.

Вот пример кода:

df = pd.DataFrame(
    {
    "booking id": [1,1,1,2,2,2,3,3,4,4,4],
    "booking type": ["initiation", "change", "change", "initiation", "change", "deletion", "reactivation", "change", "initiation", "change", "deletion"],
    "delivered": ["yes", "yes", "yes", "yes", "yes", "yes", "yes", "yes", "no", "no", "no"]
    }
)

enter image description here

Некоторые данные неверны. Если последнее обновление (последняя строка идентификатора бронирования) имеет booking type == deletion, все строки этого идентификатора бронирования должны иметь delivered = no.

В этом примере я ищу это:

df = pd.DataFrame(
    {
    "booking id": [1,1,1,2,2,2,3,3,4,4,4],
    "booking type": ["initiation", "change", "change", "initiation", "change", "deletion", "reactivation", "change", "initiation", "change", "deletion"],
    "delivered": ["yes", "yes", "yes", "no", "no", "no", "yes", "yes", "no", "no", "no"]
    }
)

enter image description here

Как мне это сделать? Большое спасибо!

Ответы [ 3 ]

2 голосов
/ 11 июня 2019

Вот один из подходов, использующий GroupBy и DataFrame.where:

df.loc[:, 'delivered'] = df.where(df.groupby('booking id')['booking type']
                                    .transform('last')
                                    .ne('deletion'), 'no')

      booking id  booking type delivered
0            1    initiation       yes
1            1        change       yes
2            1        change       yes
3            2    initiation        no
4            2        change        no
5            2      deletion        no
6            3  reactivation       yes
7            3        change       yes
8            4    initiation        no
9            4        change        no
10           4      deletion        no
2 голосов
/ 11 июня 2019

Используя transform с last, затем назначьте его обратно

df.loc[df.groupby('booking id')['booking type'].transform('last').eq('deletion'),'delivered']='No'
df
Out[112]: 
    booking id  booking type delivered
0            1    initiation       yes
1            1        change       yes
2            1        change       yes
3            2    initiation        No
4            2        change        No
5            2      deletion        No
6            3  reactivation       yes
7            3        change       yes
8            4    initiation        No
9            4        change        No
10           4      deletion        No
0 голосов
/ 11 июня 2019

Возможно, есть лучший способ сделать это с помощью groupby (), но я не знаю, как это сделать. Лучший способ, который я могу придумать, - это использовать .loc (), где вы можете найти ссылку на здесь .

ids_to_change = df.loc[df['booking type'] == 'deletion', :]['booking id']

for id in ids_to_change:
   df.loc[df['booking id'] == id, 'delivered'] = 'no'

По существу, loc возвращает часть кадра данных, соответствующую определенным характеристикам.

Во-первых, используйте loc, чтобы получить все идентификаторы с любым типом бронирования удаления. Во-вторых, прокрутите эти идентификаторы и измените все эти идентификаторы так, чтобы они поставлялись как «нет».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...