Как найти и объединить наблюдения, которые заменили другие в Python? - PullRequest
0 голосов
/ 05 августа 2020

Контекст:

  • Партнер по продажам регистрирует возможность (OppID), и она истекает через 180 дней, если не закрыта;
  • По истечении срока действия тот же партнер по продажам регистрирует новую OppID, но на самом деле это продолжение прошлого OppID;
  • В поле произвольного текста вручную (Примечания) есть ссылка на прошлый OppID со строками типа «Заменяет»;

Пример набора данных:

df <- data.frame(OppID=c("A123","A765","B456","C137","F879","H987"),OppDate=c("1/20/2020","1/21/2020","7/21/2020","1/4/2020","11/1/2020","8/21/2020"),OppStatus=c("Closed","Closed","Open","Closed","Open","Closed"),Notes=c("","","Replaces A123","","Replaces B456","Replaces A765"))

Это итоговый фрейм данных (df):

  head(df)
  OppID OppDate   OppStatus Notes
1 A123  1/20/2020 Closed    
2 A765  1/21/2020 Closed   
3 B456  7/21/2020 Open      Refers to A123
4 C137  1/4/2020  Closed    
5 F879  11/1/2020 Open      Refers to B456
6 H987  8/21/2020 Open      Refers to A765

То, что мне нужно выполнить sh - программно - примерно так ( новый фрейм данных 'df2'):

  head(df2)
  OppID OppDate   OppStatus Notes               FirstOppDate
1 C137  1/4/2020  Closed    
2 F879  11/1/2020 Open      Refers to A123,B456 1/20/2020
3 H987  8/21/2020 Open      Refers to A765      1/21/2020

Как вы можете видеть в df2, OppID A123 и B456 должны перейти на OppID F879 (поскольку F879 является продолжением B456, а B456 является продолжением A123) . Должен быть создан новый столбец для записи OppDate из самого старого OppID (в данном случае A123 еще от 20.01.2020).

Аналогичная ситуация происходит с H987 (продолжение A765). Наконец, C137 не изменился, поскольку этот OppID не является продолжением какого-либо предыдущего OppID.

Я пытался придумать способ сделать это, но пока безуспешно. Я знаю, как извлечь OppID из поля произвольного текста, но не могу придумать способ проверить эти отношения и объединить их в новейший OppID.

Есть идеи? Я надеюсь, что это имеет смысл, чего я хочу достичь (не говорящий на английском sh). Большое спасибо!

1 Ответ

1 голос
/ 06 августа 2020
import pandas as pd
columns = ['OppID', 'OppDate', 'OppStatus', 'Notes']
rows = [['A123', '1/20/2020', 'Closed' ,''], 
        ['A765', '1/21/2020', 'Closed', ''],
       ['B456', '7/21/2020', 'Open', 'Refers to A123'], 
       ['C137', '1/4/2020' , 'Closed', ''],
       ['F879', '11/1/2020', 'Open' ,'Refers to B456'],
       ['H987', '8/21/2020', 'Open', 'Refers to A765']]

df = pd.DataFrame(rows, columns = columns)

# You can use a regular expression that suits better
df['ref_opp_id'] = [x.split()[-1] if len(x)>0 else None for x in df['Notes']] 

# This can be parallelized or can be further optimized
total_ref_opps = []
first_opp_dates = []
for index, row in df.iterrows():
    total = []
    final_opp_id = row['ref_opp_id']
    first_opp_date = None
    while final_opp_id is not None:
        total.append(final_opp_id)
        first_opp_date = df[df['OppID'] == final_opp_id]['OppDate'].values[0]
        final_opp_id = df[df['OppID'] == final_opp_id]['ref_opp_id'].values[0]
    total_ref_opps.append(total)
    first_opp_dates.append(first_opp_date)

df['total_ref_opps'] = total_ref_opps
df['first_opp_dates'] = first_opp_dates

all_dup_items = [item for sublist in total_ref_opps for item in sublist]

df_new = df[~df['OppID'].isin(all_dup_items)].copy().reset_index(drop=True)

df_new.head()

Я новый участник. Пожалуйста, отметьте этот ответ как успешный, если это то, что вы ищете.

...