2015-06-30 1 views
1

После «цепочки» строк и подсчета последовательных месяцев из файла CSV.Анализ строк в строке Pandas для последовательных дат

В настоящее время я читаю CSV-файл с 5 столбцов, представляющих интерес (на основе страховых полисов):

CONTRACT_ID START-DATE   END-DATE  CANCEL_FLAG OLD_CON_ID 
123456  2015-05-30   2016-05-30  0    8788 
123457  2014-03-20   2015-03-20  0    12000 
123458  2009-12-20   2010-12-20  0    NaN 
... 

Я хочу, чтобы подсчитать количество последовательных месяцев контракта цепь идет на.

Пример: Принимая START-DATE от договора на «фронте» цепи (самый старый контракт) и END-DATE от конца цепи (самый новый контракт). Старейший контракт определяется либо до аннулированным контрактом в цепочке, либо аннулированным контрактом OLD_CON_ID.

Каждая строка представляет собой контракт, а prev_Con_ID указывает на предыдущий идентификатор контракта. Желаемый результат - это количество месяцев, в течение которых договорные цепочки возвращаются до разрыва (т. Е. У клиента не было контракта в течение определенного периода времени). Если в этом столбце ничего нет, это первый контракт в этой цепочке.

CANCEL_FLAG также должен сократить цепь, поскольку значение 1 означает, что контракт был отменен.

Текущий код подсчитывает количество активных контрактов на каждый год путем редактирования dataframe как так:

df_contract = df_contract[ 
(df_contract['START_DATE'] <= pd.to_datetime('2015-05-31')) & 
(df_contract['END_DATE'] >= pd.to_datetime('2015-05-31')) & (df_contract['CANCEL_FLAG'] == 0) 
] 
df_contract = df_contract[df_contract['CANCEL_FLAG'] == 0 
] 
activecount = df_contract.count() 
print activecount['CONTRACT_ID'] 

Вот первые 6 строк кода, в котором я создаю dataframes и настроить значения даты-времени:

file_name = 'EXAMPLENAME.csv' 
df = pd.read_csv(file_name) 
df_contract = pd.read_csv(file_name) 
df_CUSTOMERS = pd.read_csv(file_name) 

df_contract['START_DATE'] = pd.to_datetime(df_contract['START_DATE']) 
df_contract['END_DATE'] = pd.to_datetime(df_contract['END_DATE']) 

Идеальный выход что-то вроде:

FIRST_CONTRACT_ID  CHAIN_LENGTH  CON_MONTHS 
1234567     5     60 
1500001     1     4 
800      10     180 

Thos Затем будут отображаться данные точек данных.

EDIT2: Файл CSV изменен, возможно, теперь будет проще. Вопрос обновлен.

ответ

0

После долгих проб и ошибок я получил это работает!

Это находит разницу во времени между первым и последним контрактами в цепочке и находит длину цепочки.

Не самый чистый код далеко, но это работает:

test = 'START_DATE' 


df_short = df_policy[['OLD_CON_ID',test,'CONTRACT_ID']] 
df_short.rename(columns={'OLD_CON_ID':'PID','CONTRACT_ID':'CID'}, 

inplace = True) 
df_test = df_policy[['CONTRACT_ID','END_DATE']] 
df_test.rename(columns={'CONTRACT_ID':'CID','END_DATE': 'PED'}, inplace = True) 


df_copy1 = df_short.copy() 
df_copy2 = df_short.copy() 
df_copy2.rename(columns={'PID':'PPID','CID':'PID'}, inplace = True) 

df_merge1 = pd.merge(df_short, df_copy2, 
    how='left', 
    on=['PID']) 

df_merge1['START_DATE_y'].fillna(df_merge1['START_DATE_x'], inplace = True) 
df_merge1.rename(columns={'START_DATE_x':'1_EFF','START_DATE_y':'2_EFF'}, inplace=True) 

Копия, слияние, fillna и переименовывать код повторяется для 5 слиты dataframes затем:

df_merged = pd.merge(df_merge5, df_test, 
    how='right', 
    on=['CID']) 

df_merged['TOTAL_MONTHS'] = ((df_merged['PED'] - df_merged['6_EFF'] 
          )/np.timedelta64(1,'M')) 

df_merged4 = df_merged[ 
    (df_merged['PED'] >= pd.to_datetime('2015-07-06')) 
df_merged4['CHAIN_LENGTH'] = df_merged4.drop(['PED','1_EFF','2_EFF','3_EFF','4_EFF','5_EFF'], axis=1).apply(lambda row: len(pd.unique(row)), axis=1) -3 

Надеюсь, мой код понимается и поможет кому-то в будущем.

0

Не уверен, что если я полностью undertand ваше требование, но делает что-то нравится эта работа ?:

df_contract['TOTAL_YEARS'] = (df_contract['END_DATE'] - df_contract['START_DATE'] 
          )/np.timedelta64(1,'Y') 

df_contract['TOTAL_YEARS'][(df['CANCEL_FLAG'] == 1) && (df['TOTAL_YEARS'] > 1)] = 1 
+0

Взял меня слишком долго, чтобы проверить, но он правильно подсчитывает # года нахождения клиента, хотя и не последовательный. Объяснить на примере. Клиент1 имел контракт с 2006 по 2008 год, затем с 2010 по 2015 год. Код должен вернуть 5, а не 9. – VorpalBunnie

+0

Также я отредактировал исходный вопрос из-за изменения с оригинальным CSV-файлом. Надеюсь, это облегчит понимание (и выполнение). – VorpalBunnie