2017-01-30 3 views
0

У меня есть CSV-файл я импортируемый как панд dataframe, который выглядит следующим образом:Создать новый столбец в панде dataframe на основе того, появляется значение в строке в dataframe

TripId, DeviceId, StartDate,    EndDate 
817d0e7, dbf69e23, 2015-04-18T13:54:27.000Z, 2015-04-18T14:59:06.000Z 
817d0f5, fkri449g, 2015-04-18T13:59:21.000Z, 2015-04-18T14:50:56.000Z 
8145g5g, dbf69e23, 2015-04-18T15:12:26.000Z, 2015-04-18T16:21:04.000Z 
4jhbfu4, fkigit95, 2015-04-18T14:23:40.000Z, 2015-04-18T14:59:38.000Z 
8145g66, dbf69e23, 2015-04-20T11:20:24.000Z, 2015-04-20T16:22:41.000Z 
... 

Я хочу, чтобы добавить новый столбец со значением индикатора на основе того, появляется ли DeviceId в моем фреймворке данных, после 1-го StartDate после текущего EndDate. Так что мой новый dataframe должен выглядеть следующим образом:

TripId, DeviceId, StartDate,    EndDate,     newcol 
817d0e7, dbf69e23, 2015-04-18T13:54:27.000Z, 2015-04-18T14:59:06.000Z, 1 
817d0f5, fkri449g, 2015-04-18T13:59:21.000Z, 2015-04-18T14:50:56.000Z, 0 
8145g5g, dbf69e23, 2015-04-18T15:12:26.000Z, 2015-04-18T16:21:04.000Z, 0 
4jhbfu4, fkigit95, 2015-04-18T14:23:40.000Z, 2015-04-18T14:59:38.000Z, 0 
8145g66, dbf69e23, 2015-04-20T11:20:24.000Z, 2015-04-20T16:22:41.000Z, 0 
... 

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

df['newcol'] = np.where(df['DeviceId'].isin(df['DeviceId']) and , 1, 0) 

Одна проблема заключается в том, что я не знаю, как найти идентификатор устройства в dataframe за исключением текущей строки, а другой в том, что я не знаю, как решить этот вопрос времени.

EDIT: Я работаю над этим немного, и мой новый код теперь:

df['UniqueId'] = range(0, 14571, 1) 

df['StartDate'] = pd.to_datetime(df['StartDate']) 
df['EndDate'] = pd.to_datetime(df['EndDate']) 

df2 = df.loc[df.duplicated(subset=['DeviceId'],keep=False)] 
#Returns list of trips with repeated deviceid 
DeviceIds = df2['DeviceId'].tolist() 
DeviceIds = list(set(DeviceIds)) 
for ID in DeviceIds: 
    temp = df2.loc[df2['DeviceId'] == ID] 
    temp.sort_values(by='StartDate') 
    temp['PreviousEnd'] = temp['EndDate'].shift(periods=1) 
    temp['Difference'] = temp['StartDate'] - temp['PreviousEnd'] 
    temp['Difference'] = [1 if x < pd.Timedelta('1H') 
         else 0 for x in temp['Difference']] 
    temp = temp[['UniqueId','Difference']] 
    df.join(temp, on='UniqueId', how='left',rsuffix='2') 

Чем она создает правильную временную dataframe, но я не могу присоединиться к значениям в Difference к первоначальному dataframe

+0

Нет проблем, я пытаюсь добавить комментарий к моему ответу. Но если я не знаю желаемого результата, я не могу проверить, является ли мое решение тем, что вы хотите. – jezrael

+0

также, возможно, необходимо сравнить с значением 'min', а не' max' – jezrael

ответ

0

Вы можете groupby и сравнить столбец EndDate с max значением startDate с 1H:

def f(x): 
    #print (x) 
    #not sure if 1 Hour as added to startDate and if is necessary compare 
    #with ==, <, > 
    return x.EndDate > (x.startDate + pd.Timedelta('1H')).max() 

mask = df.groupby('DeviceId').apply(f).reset_index(level=0, drop=True).reindex(df.index) 
print (mask) 
0 False 
1 False 
2 False 
3 False 
4  True 
Name: EndDate, dtype: bool 

Последнее преобразование boolean mask в int:

df['new_col'] = mask.astype(int) 
print (df) 
    TripId DeviceId   startDate    EndDate new_col 
0 817d0e7 dbf69e23 2015-04-18 13:54:27 2015-04-18 14:59:06  0 
1 817d0f5 fkri449g 2015-04-18 13:59:21 2015-04-18 14:50:56  0 
2 8145g5g dbf69e23 2015-04-18 15:12:26 2015-04-18 16:21:04  0 
3 4jhbfu4 fkigit95 2015-04-18 14:23:40 2015-04-18 14:59:38  0 
4 8145g66 dbf69e23 2015-04-20 11:20:24 2015-04-20 16:22:41  1 
+0

Теперь у меня есть желаемый результат в моем вопросе. Я хотел бы, чтобы new_col был 1, если в ядре данных есть строка с таким же идентификатором deviceId и дата начала не более чем через 1 час после даты окончания исходной строки. –

+0

Как вы думаете, ваше решение с 'df ['UniqueId']'? – jezrael

+0

нет, мое решение незакончено. Я добавил uniqueId, поэтому, как только я обнаружил, какие строки имеют повторяющееся deviceId, я могу перевести его обратно в свой первый Dataframe –

0

мне удалось заставить его работать, код, который я использовал, был:

df['UniqueId'] = range(0, 14571, 1) 

df['StartDate'] = pd.to_datetime(df['StartDate']) 
df['EndDate'] = pd.to_datetime(df['EndDate']) 
#converts dates to dateTime 
df2 = df.loc[df.duplicated(subset=['DeviceId'],keep=False)] 
#Returns list of trips with repeated deviceid 

DeviceIds = df2['DeviceId'].tolist() 
DeviceIds = list(set(DeviceIds)) 
df3 = pd.DataFrame(columns = ['UniqueId','Difference']) 
for ID in DeviceIds: #creats mini dataframes for every DeviceId 
    temp = df2.loc[df2['DeviceId'] == ID] 
    temp.sort_values(by='StartDate') 
    temp['PreviousEnd'] = temp['EndDate'].shift(periods=1) 
    temp['Difference'] = temp['StartDate'] - temp['PreviousEnd'] 
    temp['Difference'] = [1 if x < pd.Timedelta('24H') 
         else 0 for x in temp['Difference']] 
    temp = temp[['UniqueId','Difference']] 
    df3 = pd.concat([df3,temp]) 
df.set_index('UniqueId').join(df3.set_index('UniqueId'),how='left') 
Смежные вопросы