首页 > 解决方案 > 按字符串列表的顺序解析 Pandas 数据帧

问题描述

我有一个正在转换为 pandas 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)

标签: pythonpandasloopsdataframe

解决方案


推荐阅读