【问题标题】:Convert 2-column counter-like csv file to Python collections.Counter?将 2 列类似计数器的 csv 文件转换为 Python 集合。计数器?
【发布时间】:2019-05-07 15:19:57
【问题描述】:

我有一个逗号分隔 (,) 制表符分隔 (\t) 的文件。

68,"phrase"\t
485,"another phrase"\t
43, "phrase 3"\t

有没有简单的方法把它扔进 Python Counter

【问题讨论】:

  • 我的意思是,没有专门针对您的文本文件的内置方法,但解析起来应该非常简单......
  • 编写代码应该很简单,为什么不试试呢?
  • 我已经尝试过了,但我的解决方案并不像我希望的那么简单。 ???我在想也许这里有人有更好的尝试。此外,如果您搜索“将 csv 列转换为计数器”或类似的内容,Google 上不会出现任何内容。我想我会提出一些人们可以找到的东西。如果没有更好的结果,我会发布我的答案。
  • 那不是真正的计数器;它是一个包含字符串和 int 的元组列表。那是你要的吗?计数器是动态的吗?
  • 好点dawg。我从问题中删除了它。

标签: python python-3.x python-collections


【解决方案1】:

我无法放弃,偶然发现我认为是赢家。

在测试中很明显循环遍历csv.DictReader 的行是最慢的部分;大约需要 40 秒中的 30 秒。

我把它改成简单的csv.reader 看看我会得到什么。这导致了列表行。我将它包裹在dict 中,看看它是否直接转换。确实如此!

然后我可以遍历本地字典而不是 csv.DictReader

结果...在 3 秒内完成 400 万行! ?

def convert_counter_like_csv_to_counter(file_to_convert):
    with file_to_convert.open(encoding="utf-8") as f:
        csv_reader = csv.reader(f, delimiter="\t")
        d = dict(csv_reader)
        the_counter = Counter({phrase: int(float(count)) for count, phrase in d.items()})

    return the_counter

【讨论】:

    【解决方案2】:

    你可以使用字典理解,被认为更多的是pythonicit can be marginally faster:

    import csv
    from collections import Counter
    
    
    def convert_counter_like_csv_to_counter(file_to_convert):
        with file_to_convert.open(encoding="utf-8") as f:
            csv_reader = csv.DictReader(f, delimiter="\t", fieldnames=["count", "title"])
            the_counter = Counter({row["title"]: int(float(row["count"])) for row in csv_reader})
        return the_counter
    

    【讨论】:

    • 有趣...这始终快了大约 10%。 ➕1
    【解决方案3】:

    这是我最好的尝试。它可以工作,但不是最快的。
    在 400 万行输入文件上运行大约需要 1.5 分钟。
    根据 Daniel Mesejo 的建议,现在在 400 万行输入文件上需要大约 40 秒。

    注意:csv中的count值可以是科学计数法,需要转换。因此int(float( 铸造。

    import csv
    from collections import Counter
    
    def convert_counter_like_csv_to_counter(file_to_convert):
    
        the_counter = Counter()
        with file_to_convert.open(encoding="utf-8") as f:
            csv_reader = csv.DictReader(f, delimiter="\t", fieldnames=["count", "title"])
            for row in csv_reader:
                the_counter[row["title"]] = int(float(row["count"]))
    
        return the_counter
    

    【讨论】:

    • 为什么不简单地the_counter[row["title"]] = int(float(row["count"]))。你也愿意用 pandas 吗?
    • 酷。更新了我的答案以反映您的建议。这将时间缩短了一半。谢谢!我宁愿不使用熊猫,但有更多的答案供人们投票也无妨。 ?
    • 在之前的评论中我想念你可以做the_counter[row["title"]] = int(row["count"])。不需要浮动。
    • 数字是科学计数法吗?
    猜你喜欢
    • 1970-01-01
    • 2018-08-11
    • 2015-12-13
    • 2016-03-12
    • 1970-01-01
    • 1970-01-01
    • 2015-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多