Parse Pandas Dataframe в порядке списка строк - PullRequest
0 голосов
/ 31 октября 2019

У меня есть файл журнала, который я преобразовываю в pandas df. Мне нужно найти конкретные строки журнала из df и рассчитать время между этими линиями, следовательно, разделить весь журнал на несколько этапов.

Df пример:

log_level  timestamp               message
INFO       2019-10-31 12:00        A
INFO       2019-10-31 12:02        b
INFO       2019-10-31 12:00        c
INFO       2019-10-31 12:04        d
INFO       2019-10-31 12:00        e
INFO       2019-10-31 12:06        f
INFO       2019-10-31 12:00        g
INFO       2019-10-31 12:08        h
INFO       2019-10-31 12:10        i
INFO       2019-10-31 12:12        j
INFO       2019-10-31 12:14        k
INFO       2019-10-31 12:16        l
INFO       2019-10-31 12:18        m
INFO       2019-10-31 12:18        n

msg_list = ['a', 'd','g','n', 'k']

Здесь «a» - «d» становится фазой, «d» - «g» другой и так далее до конца журнала. У меня есть около 40000 строк журнала, которые мне нужно разделить.

Каков наилучший и наиболее оптимизированный способ сделать это, поскольку мне нужно проанализировать около 400 нечетных журналов.

Я использую str.contains для поиска начального и конечного индексов и получениявремя между ними, но я чувствую, что оно недостаточно эффективно, потому что каждый раз просматривает Dataframe сверху вниз, чтобы найти строки.

Можно ли просматривать кадр данных только один раз, скажем, если я найду сообщение 'a', тогда я ищу следующее сообщение 'd' и в следующий раз перехожу от 'd' к следующему сообщению 'g',с каким-то своего рода позиционным индексом?

Часть моего кода:

@property
    def start_idx(self):
        if self._start_idx is None:
            self._start_idx = self.main_df.index[self.main_df['message'].str.contains(self.start_message)][0]
            print(self._start_idx)
        return self._start_idx

    @property
    def end_idx(self):
        if self._end_idx is None:
            self._end_idx = self.main_df.index[self.main_df['message'].str.contains(self.end_message)][0]
            print(self._end_idx)
        return self._end_idx

    @property
    def start_time(self):
        if self._start_time is None:
            self._start_time = self.phase_df.loc[self.start_idx, 'timestamp']
        return self._start_time

    @property
    def end_time(self):
        if self._end_time is None:
            self._end_time = self.phase_df.loc[self.end_idx, 'timestamp']
        return self._end_time

    @property
    def phase_df(self):
        if self._phase_df is None:
            self._phase_df = self.main_df.iloc[self.start_idx: self.end_idx]

        return self._phase_df

    @property
    def phase_time(self):
        if self._phase_time is None:
            self._phase_time = (self.end_time - self.start_time) / np.timedelta64(1, 's')

        return int(self._phase_time)

Я вызывал эту часть кода несколько раз для разных начальных и конечных сообщений, которые я нахожу.

Ожидаемый вывод (в отдельном df):

File    Phase1    Phase2    .... Phase N
Log1     120       120             120      (Time in seconds/minutes)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...