Фланкирование данных с помощью сдвига - PullRequest
0 голосов
/ 12 сентября 2018

Как точно работает shift () в этом коде.Я пытаюсь получить некоторые значения True в моем фрейме данных, а затем расширить свой выбор до следующих 4 False значений.Пример моего DataFrame:

df Out[89]: TRACK_ID FRAME match 290 1667.0 350.0 False 291 1667.0 352.0 False 292 1667.0 353.0 False 293 1667.0 354.0 False 294 1668.0 348.0 False 295 1668.0 349.0 False 296 1668.0 350.0 False 297 1668.0 351.0 True 298 1668.0 352.0 True 299 1668.0 353.0 True 300 449.0 87.0 False 301 449.0 88.0 False 302 449.0 89.0 False 303 449.0 90.0 False 304 449.0 91.0 False 305 449.0 92.0 False

Я использую эту строку кода, чтобы извлечь строки True и сразу 4 строки вверх и вниз:

df1 = df[df.match | df.match.shift(np.round(-4,0)) | df.match.shift(np.round(4,0))] 

Однако мой вывод пропускает (удаляет) первый индекс вверх и вниз (индекс 296 и 300):

df1 Out[97]: TRACK_ID FRAME match 293 1667.0 354.0 False 294 1668.0 348.0 False 295 1668.0 349.0 False 297 1668.0 351.0 True 298 1668.0 352.0 True 299 1668.0 353.0 True 301 449.0 88.0 False 302 449.0 89.0 False 303 449.0 90.0 False

Я не могу понять, почему это происходит, любые предложения приветствуются!

1 Ответ

0 голосов
/ 12 сентября 2018

Ваше условие - маска, которая "сдвигает" значения на 4 строки, не более того.

df.match | df.match.shift(np.round(-4,0)) | df.match.shift(np.round(4,0))
#290    False
#291    False
#292    False
#293     True
#294     True
#295     True
#296    False
#297     True
#298     True
#299     True
#300    False
#301     True
#302     True
#303     True
#304    False
#305    False

Вы фильтруете фрейм данных вместе с ним, поэтому он «удаляет» строки, где ваше условие не соответствует действительности. Похоже, вы бы предпочли пометить эти строки как ложные, и в этом случае вы не хотите фильтровать, вы хотите обновить фрейм данных

df['updated_match'] = df.match | df.match.shift(np.round(-4,0)) | df.match.shift(np.round(4,0))

Тогда df выглядит так:

   TRACK_ID FRAME   match   updated_match
290 1667.0  350.0   False   False
291 1667.0  352.0   False   False
292 1667.0  353.0   False   False
293 1667.0  354.0   False   True
294 1668.0  348.0   False   True
295 1668.0  349.0   False   True
296 1668.0  350.0   False   False
297 1668.0  351.0   True    True
298 1668.0  352.0   True    True
299 1668.0  353.0   True    True
300 449.0   87.0    False   False
301 449.0   88.0    False   True
302 449.0   89.0    False   True
303 449.0   90.0    False   True
304 449.0   91.0    False   False
305 449.0   92.0    False   False

EDIT: Перечитал вопрос и понял твою проблему.

Я думаю, что вместо использования shift() вам нужен скользящий максимум в 4-рядном окне. Используйте .rolling() в обоих направлениях (вперед и назад).

df1 = 
df[df.match |
   df['match'].iloc[::-1].rolling(window=4).max().fillna(0).astype(bool) |
   df['match'].rolling(window=4).max().fillna(0).astype(bool)
  ]

Выход:

#   TRACK_ID    FRAME   match
#294    1668.0  348.0   False
#295    1668.0  349.0   False
#296    1668.0  350.0   False
#297    1668.0  351.0   True
#298    1668.0  352.0   True
#299    1668.0  353.0   True
#300    449.0   87.0    False
#301    449.0   88.0    False
#302    449.0   89.0    False

Это сохраняет 296 и 300, которые вы вызвали.

...