2016-10-31 7 views
1
Msgtype Date ConvID message 
enquire 12/1 689 I want your car 
reply 12/3 689 it is available 
reply 12/4 689 rent please? 
reply 12/6 689 $200 
accept 12/8 689 please pay through CC 
reply 12/8 689 thank you, what about fuel? 
reply 12/8 689 you have to take care 
enquire 12/3 690 Looking for car 
reply 12/4 690 available 
accept 12/5 690 paid 
reply 12/6 690 thank you 

Я хочу объединить эти данные с помощью ConvID и отсортировать их по дате. Я хочу, чтобы строки до «Msgtype» = accept для этого конкретного ConvID. Цель для анализа данных сообщений до запроса на бронирование принимается для конкретного ConvID. поэтому для ConvID = 689 мне нужны строки до «Msgtype» = accept. Остальные строки после «accept» не требуются.Несколько рядов нарезки в пандах по состоянию на ячейке

Например: Эти два не требуются для ConvID = 689

Msgtype Date ConvID message 
    reply 12/8 689 thank you, what about fuel? 
    reply 12/8 689 you have to take care 

Точно так же эта строка не является обязательным для ConvID = 690

Msgtype Date ConvID message 
reply 12/6 690 thank you 

ответ

1

Я думаю, вы можете использовать:

mask1 = (df.Msgtype == 'accept') 
mask = mask1.groupby([df.ConvID]).apply(lambda x: x.shift().fillna(False).cumsum()) == 0 

print (df[mask].sort_values(['ConvID','Date'])) 
    Msgtype Date ConvID    message 
0 enquire 12/1  689  I want your car 
1 reply 12/3  689  it is available 
2 reply 12/4  689   rent please? 
3 reply 12/6  689     $200 
4 accept 12/8  689 please pay through CC 
7 enquire 12/3  690  Looking for car 
8 reply 12/4  690    available 
9 accept 12/5  690     paid 

Пояснения:

#mask where is 'accept' 
mask1 = (df.Msgtype == 'accept') 
print (mask1) 
0  False 
1  False 
2  False 
3  False 
4  True 
5  False 
6  False 
7  False 
8  False 
9  True 
10 False 
Name: Msgtype, dtype: bool 

#per group shift, replace NaN by False and cumulative sum 
print (mask1.groupby([df.ConvID]).apply(lambda x: x.shift().fillna(False).cumsum())) 
0  0 
1  0 
2  0 
3  0 
4  0 
5  1 
6  1 
7  0 
8  0 
9  0 
10 1 
Name: Msgtype, dtype: int32 
#where output of groupby is 0 
mask = mask1.groupby([df.ConvID]).apply(lambda x: x.shift().fillna(False).cumsum()) == 0 
print (mask) 
0  True 
1  True 
2  True 
3  True 
4  True 
5  False 
6  False 
7  True 
8  True 
9  True 
10 False 
Name: Msgtype, dtype: bool 

#boolean indexing and sorting 
print (df[mask].sort_values(['ConvID','Date'])) 
    Msgtype Date ConvID    message 
0 enquire 12/1  689  I want your car 
1 reply 12/3  689  it is available 
2 reply 12/4  689   rent please? 
3 reply 12/6  689     $200 
4 accept 12/8  689 please pay through CC 
7 enquire 12/3  690  Looking for car 
8 reply 12/4  690    available 
9 accept 12/5  690     paid 
+0

Вы получаете 'ValueError: может ли сравнивать только идентичные объекты серии? – jezrael

+0

Я пытаюсь реализовать свое решение, просто дай мне немного времени. Данные требуют много времени для обработки. Я скоро отправлю свои отзывы – dsl1990

+0

Большое спасибо за ваше время и терпение. Этот ответ работает для меня. – dsl1990

0

Easy:

for name, grp in df.groupby('ConvID'): 
    grp.sort_values('Date', inplace=True) 
    accept_date = grp.loc[grp['Msgtype'] == 'accept', 'Date'] 
    req = grp[grp['Date'] < accept_date] 
    # Or, you can use index, like so: 
    # grp = grp.sort_values('Date').reset_index(drop=True) 
    # req = grp.iloc[:grp[grp['Msgtype'] == 'accept'].index.values[0], :] 

req будет иметь только необходимые строки, которые можно использовать для анализа.

+0

1-е решение: ValueError: может сравнивать только объекты с одинаковой меткой 2-е решение: TypeError: не может индексировать срез на с этими индексаторами [Int64Index ([0], dtype = ' int64 ')] из ошибка находится на этапе' req = ' – dsl1990

+0

Для 1-го решения конвертируйте свои столбцы в datetime с помощью 'pd.to_datetime'. Для 2-го решения панды недавно немного изменили индексы. Вместо этого вы можете использовать 'req = grp.iloc [: grp [grp ['Msgtype'] == 'accept']. Index.values ​​[0],:]', как я отредактировал в своем ответе. – Kartik

+0

та же ошибка для 1-го решения и для 2-го решения: IndexError: индекс 0 за пределами оси 0 с размером 0 – dsl1990

 Смежные вопросы

  • Нет связанных вопросов^_^