【问题标题】:Count occurrences of each word in a given text file stored based on date根据日期计算给定文本文件中每个单词的出现次数
【发布时间】:2019-11-26 17:46:13
【问题描述】:

我目前有一个文本文件,其中包含某人发送消息时的时间戳和姓名。请看下文:Attachment

8/29/19, 2:03 PM - Michael: ...
8/29/19, 3:05 PM - Frank: ...
8/29/19, 4:01 PM - Tom: ...
8/29/19, 5:26 PM - Amy: ...
8/29/19, 6:46 PM - Tom: ...
8/29/19, 7:24 PM - Frank: ...
8/29/19, 9:55 PM - Amy: ...
8/30/19, 11:35 AM - Frank: ...
8/30/19, 12:39 PM - Johnny: ...
9/3/19, 1:18 AM - Frank: ...
9/3/19, 2:23 AM - Frank: ...
9/3/19, 3:16 PM - Frank: ...
9/3/19, 4:53 PM - Johnny: ...
9/4/19, 9:01 AM - Frank: ...
9/4/19, 11:45 AM - Frank: ...
9/4/19, 1:04 PM - Johnny: ...
9/4/19, 1:42 PM - Johnny: ...
9/4/19, 2:03 PM - Amy: ...
9/4/19, 4:12 PM - Johnny: ...
9/4/19, 6:27 PM - Amy: ...
9/4/19, 9:08 PM - Johnny: ...
.   .      .
.   .      .
.   .      .

我想根据python中的日期计算一个人发送消息的发生次数。我想输出以下内容:Attachment

                 Michael  Frank   Tom    Amy     Johnny

      8/29/2019     1        2      2     2       0
      8/30/2019     0        1      0     0       1
      8/31/2019     0        0      0     0       0
      9/1/2019      0        0      0     0       0
      9/2/2019      0        0      0     0       0
      9/3/2019      0        3      0     0       1
      9/4/2019      0        2      0     2       4
      9/5/2019                  
      9/6/2019                  
      9/7/2019                  
      9/8/2019                  

第一次发帖,如果格式不正确,请见谅。非常感谢。

【问题讨论】:

  • 我自己对 SO 还很陌生,所以我不知道这里的正常情况。但是,我认为您 @Michael 应该可能会在您需要的 Python 程序中提供一些开始。在我向您建议程序结构之前,您需要回答:1)您希望如何确定要使用的开始日期(可能根据第一行输入即时执行此操作)2)您希望如何建立名称集(也使用第一个日期完成,或使用所有日期完成,即通过读取整个输入?) 3)您希望能够处理大量输入还是仅处理适度的输入?

标签: python date text count


【解决方案1】:

您可以使用 pandas 来提供帮助:

from io import StringIO
import pandas as pd

txtfile=StringIO("""8/29/19, 2:03 PM - Michael: ...
8/29/19, 3:05 PM - Frank: ...
8/29/19, 4:01 PM - Tom: ...
8/29/19, 5:26 PM - Amy: ...
8/29/19, 6:46 PM - Tom: ...
8/29/19, 7:24 PM - Frank: ...
8/29/19, 9:55 PM - Amy: ...
8/30/19, 11:35 AM - Frank: ...
8/30/19, 12:39 PM - Johnny: ...
9/3/19, 1:18 AM - Frank: ...
9/3/19, 2:23 AM - Frank: ...
9/3/19, 3:16 PM - Frank: ...
9/3/19, 4:53 PM - Johnny: ...
9/4/19, 9:01 AM - Frank: ...
9/4/19, 11:45 AM - Frank: ...
9/4/19, 1:04 PM - Johnny: ...
9/4/19, 1:42 PM - Johnny: ...
9/4/19, 2:03 PM - Amy: ...
9/4/19, 4:12 PM - Johnny: ...
9/4/19, 6:27 PM - Amy: ...
9/4/19, 9:08 PM - Johnny: ...""")

df = pd.read_csv(txtfile, sep=',|-|:', header=None, index_col=[0], engine='python')
df_out = df[3].str.get_dummies().sum(level=0)
print(df_out)

输出:

          Amy   Frank   Johnny   Michael   Tom
0                                             
8/29/19     2       2        0         1     2
8/30/19     0       1        1         0     0
9/3/19      0       3        1         0     0
9/4/19      2       2        4         0     0

【讨论】:

    【解决方案2】:

    通过只在文件中迭代一次来做到这一点的一种方法是在 defaultdict 的帮助下:

    from collections import defaultdict
    
    occurrences = defaultdict(lambda: defaultdict(int))
    
    with open('filename.txt', 'r') as f:
        for line in f.readlines():
            date = line.split(', ')[0]
            name = line.split(' - ')[1].split(': ')[0]
            occurrences[date][name] += 1
    

    出现次数将有以下数据:

    8/29/19: {'Michael': 1, 'Frank': 2, 'Tom': 2, 'Amy': 2}
    8/30/19: {'Frank': 1, 'Johnny': 1}
    9/3/19: {'Frank': 3, 'Johnny': 1}
    9/4/19: {'Frank': 2, 'Johnny': 4, 'Amy': 2}
    

    编辑:这将打印出 OP 想要的确切输出:

    from collections import defaultdict
    from datetime import datetime, timedelta
    
    occurrences = defaultdict(lambda: defaultdict(int))
    
    with open('filename.txt', 'r') as f:
        lines = f.readlines()
        start_date = lines[0].split(' - ')[0]
        start_date = datetime.strptime(start_date, '%m/%d/%y, %I:%M %p')
        end_date = lines[-1].split(' - ')[0]
        end_date = datetime.strptime(end_date, '%m/%d/%y, %I:%M %p')
    
        dates = []
    
        for n in (range(int((end_date - start_date).days))):
            single_date = start_date + timedelta(n)
            dates.append(single_date.date())
    
        authors = set()
    
        for line in lines:
            name = line.split(' - ')[1].split(': ')[0]
            authors.add(name)
            date = line.split(' - ')[0]
            date = datetime.strptime(date, '%m/%d/%y, %I:%M %p').date()
            occurrences[date][name] += 1
    
        print('\t\t', end='')
        for name in authors:
            print (name, end='\t')
        print()
    
        for date in dates:
            print(date.strftime('%m/%d/%y'), end='\t')
            for name in authors:
                print(occurrences[date][name], end='\t')
            print()
    

    这个解决方案有改进的余地,因为它完全无视性能。

    【讨论】:

    • 此答案不按日期对输出进行排序。它只假设 defaultdict 将按排序键顺序返回(我认为这不是保证)。更重要的是,将日期排序为字符串不会给您排序日期。例如,这些日期将如何排序:8/29/19、1/29/19、11/29/19、2/29/18?其次,这个答案应该以指示的格式提供输出 - 也就是说,一个表格,其中包含该日期没有计数的单元格的列和零。
    • 哦,这个答案没有将日期填充为全零,如示例输出中所示。 @Coka - 我不想批评。只是在这个“有趣的小练习”中指出薄弱点
    • @BillHuneke 完全正确。如果一个人没有在该日期发送消息,我希望输出在一个带有 0 的表中
    • 在这种情况下,解决方案变得更加复杂。您需要建立一个开始日期和结束日期之间的日期列表,以及所有作者的列表。然后填充表格会更容易。
    • 我用一个解决方案编辑了我的原始答案,该解决方案可以按照@Michael 的要求打印出确切的输出。
    猜你喜欢
    • 2018-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    • 2017-08-14
    相关资源
    最近更新 更多