首页 > 解决方案 > 使用 python 和 pandas 处理日期和时间

问题描述

我正在做一个涉及分析 WhatsApp 日志数据的项目。预处理日志文件后,我有一个如下所示的表:

DD/MM/YY | hh:mm | name | text | 

我可以建立一个图表,通过与我的朋友聊天,我绘制了每月文本数量和每月平均单词数的图表,但我有一些问题:

这是我项目的 GitLab 页面。

  def wapp_split(line):

      splitted = line.split(',')
      Data['date'].append(splitted[0])
      splitted = splitted[1].split(' - ')
      Data['time'].append(splitted[0])
      splitted = splitted[1].split(':')
      Data['name'].append(splitted[0])
      Data['msg'].append(splitted[1][0:-1])


   def wapp_parsing(file):
      with open(file) as f:
          data = f.readlines()
          for line in data:
              if (line[17:].find(':')!= -1):
                  if (line[0] in numbers) and (line[1]in numbers):

                      prev = line[0:35]
                      wapp_split(line)
                  else:

                      line = prev + line
                      wapp_split(line)

这些是脚本的主要功能。WhatsApp 日志的格式如下:

DD/MM/YY, hh:mm - Name Surname: This is a text sent using WhatsApp

解析函数只是获取文件并将每一行发送到 split函数。那些如果在解析功能中只是避免来自 WhatsApp 的消息,而不是来自被解析的聊天中的人。

标签: pythonpandas

解决方案


假设您拥有的表是一个如下所示的 .csv 文件(称为 msgs.csv):

date;time;name;text
22/10/2018;11:30;Maria;Hello how are you
23/10/2018;11:30;Justin;Check this
23/10/2018;11:31;Justin;link
22/11/2018;11:30;Maria;Hello how are you
23/11/2018;11:30;Justin;Check this
23/12/2018;11:31;Justin;link
22/12/2018;11:30;Maria;Hello how are you
23/12/2018;11:30;Justin;Check this
23/01/2019;11:31;Justin;link
23/04/2019;11:30;Justin;Check this
23/07/2019;11:31;Justin;link

现在,您可以使用 pandas 以表格格式导入此 csv,该格式将日期和时间都识别为时间戳对象,然后您可以按月对数据进行分组进行计算。

import pandas as pd
dateparse = lambda x: pd.datetime.strptime(x, '%d/%m/%Y %H:%M')
df = pd.read_csv('msgs.csv', delimiter=';', parse_dates=[['date', 'time']], date_parser=dateparse)

per = df.date_time.dt.to_period("M")
g = df.groupby(per)

for i in g:
    print('#######')
    print('year: {year} ; month: {month} ; number of messages: {n_msgs}'
          .format(year=i[0].year, month=i[0].month, n_msgs=len(i[1])))

编辑 - 没有关于特定月份的信息 = 0 条消息:

为了在没有发送消息的月份中获得 0,您可以这样做(看起来也比上面更好):

import pandas as pd
dateparse = lambda x: pd.datetime.strptime(x, '%d/%m/%Y %H:%M')
df = pd.read_csv('msgs.csv', delimiter=';', parse_dates=[['date', 'time']], date_parser=dateparse)

# create date range from oldest message to newest message
dates = pd.date_range(*(pd.to_datetime([df.date_time.min(), df.date_time.max()]) + pd.offsets.MonthEnd()), freq='M')

for i in dates:
    df_aux = df[(df.date_time.dt.month == i.month) & (df.date_time.dt.year == i.year)]

    print('year: {year} ; month: {month} ; number of messages: {n_msgs}'
          .format(year=i.year, month=i.month, n_msgs=len(df_aux)))

编辑 2:将日志解析为 pandas 数据框:

df = pd.DataFrame({'logs':['DD/MM/YY, hh:mm - Name Surname: This is a text sent using WhatsApp',
                   'DD/MM/YY, hh:mm - Name Surname: This is a text sent using WhatsApp']})

pat = re.compile("(?P<date>.*?), (?P<time>.*?) - (?P<name>.*?): (?P<message>.*)")

df_parsed = df.logs.str.extractall(pat)

推荐阅读