在Python中实时计算csv列出现的次数

13 浏览
0 Comments

在Python中实时计算csv列出现的次数

我有一个包含2亿行的csv文件。

加载这个文件的最佳方式是逐行使用csv reader(因为我有很多这样的文件,所以稍后通过并行化代码不需要加载大量数据集和超负荷运行内存)。

我试图计算某一列中值的出现次数,并将其值和频率记录在一个字典中。例如,计算某列中唯一ID的数量以及这些ID出现的次数。

以下是我如何实现这一点的示例:

import csv

from tqdm import tqdm

field_names = ['A','B','ID','C','D']

filename = '/PATH/file'

ID_dict = {}

with open(data_path+filename) as f:

reader = csv.DictReader(f,field_names,delimiter=',')

for row in tqdm(reader):

label = row['ID']

if label not in ID_dict.keys():

ID_dict[label] = 0

ID_dict[label] += 1

因此,这里我感兴趣的是标有“ID”的列,但是假设它有大约2亿个条目。

遍历所有这些行并填充一个字典是很慢的(在我的机器上需要大约10个小时)。

另一种方法是将值附加到一个新数组中,然后使用Counter来找到每个唯一元素的出现次数也太慢了(参见How do I count unique values inside a list)。

我是否忽略了更快的方法?也许有一种更快的Pandas方法?

先感谢您的帮助。

0
0 Comments

文章标题:Python中实时计算CSV列出现次数的方法

在Python中,有一个问题是如何实时计算CSV文件中某一列的出现次数。下面将介绍这个问题的出现原因以及解决方法。

问题出现的原因是,在处理CSV文件时,我们经常需要统计某一列中不同元素的出现次数。这对于数据分析和处理来说是非常常见的需求。然而,传统的方法需要先读取整个CSV文件,然后再进行统计,这在处理大型文件时效率较低。

为了解决这个问题,可以使用Python的pandas库来实现实时计算CSV列出现次数的功能。具体的解决方法如下:

1. 使用groupby函数进行计数:使用df.groupby('ID').count()可以统计CSV文件中某一列(例如ID列)中每个元素的出现次数。这个方法会返回一个包含统计结果的DataFrame。

2. 使用value_counts函数进行计数:使用df['ID'].value_counts()可以统计CSV文件中某一列的每个元素的出现次数,并按照出现次数从高到低进行排序。这个方法会返回一个包含统计结果的Series。

通过上述两种方法,我们可以轻松地实现实时计算CSV列出现次数的功能。这些方法在处理大型文件时效率较高,能够快速准确地得到统计结果。

需要注意的是,对于非常大的CSV文件,这些方法仍然需要读取整个文件才能进行统计,因此可能会有一定的性能开销。另外,pandas库在底层使用了csv.reader()函数来读取CSV文件,因此速度可能会受到一定的限制。

总结起来,通过使用pandas库中的groupby函数和value_counts函数,我们可以在Python中实现实时计算CSV列出现次数的功能。这些方法简单易用,效率较高,能够满足大部分的统计需求。在实际应用中,可以根据具体情况选择合适的方法来进行统计分析。

0
0 Comments

使用DictReader()函数会导致性能下降,因为它会将每一行转换成一个字典,而在这个问题中并不需要这种转换。可以使用普通的reader,并访问每一行的第三列。

进一步提高性能的方法是使用Counter()对象,它会自动处理计数为0的情况。另外,通过使用newline=''参数打开文件,可以略微提高性能。

如果使用map()函数和operator.itemgetter(),可以避免循环开销,并直接将id传递给Counter()。

对于处理2亿行数据来说,需要很大的计算量。在我的测试中,我使用Faker生成了100万行半真实数据,并将这些行复制了200次,生成了12GB的数据。在我的2017款Macbook Pro上,使用tqdm库的处理时间为6分钟,不使用tqdm库的处理时间为5分14秒。在我的测试中,tqdm库每次迭代增加的时间约为60纳秒,但在我的测试中,它似乎增加了3到4倍的时间。

使用Pandas读取数据的速度与上述方法相当,因为Pandas的read_csv()函数是建立在csv.reader()之上的。然而,它需要大量的内存来处理这200万行的数据。如果要处理这么大量的数据,需要按块读取数据并汇总结果。

通过进行速度测试,可以比较你的版本(包括使用和不使用tqdm库的版本),Pandas和上述方法的性能。我们使用了一个包含大约100个唯一id的测试集来进行公平比较。以下是设置测试数据和运行测试的代码:

测试结果显示,使用DictReader()和Python的for循环导致你的版本的运行时间是其他方法的6到7倍。tqdm库的开销在关闭了stderr后降低到了0.3纳秒;如果不使用with redirect_stderr()上下文管理器,输出更加冗长,时间增加到了50微秒,即每次迭代约为2纳秒。

Pandas在这里也表现得很好!但是,如果不将占用几GB内存的200万行数据全部读入内存(而是使用实际数据集,而不是空列),处理速度将会慢得多,也许你的机器无法承受。在这种情况下,使用Counter()就不需要几GB的内存了。

如果你需要对CSV数据集进行更多的处理,那么使用SQLite也是一个不错的选择。在这种情况下,甚至不需要使用Python,只需要使用SQLite命令行工具直接导入CSV数据。

如果用户想要并行加载多个文件,那么使用pandas的value_counts()函数需要预先加载整个数据集,这样的内存要求太大了。

如果你需要对每个键的值进行累加而不是计数,可以使用defaultdict(int)字典来保存每个id的累加和,然后使用summed[row[2]] += int(row[some_other_column_index])来计算每个ID的累加总和。

以上是对原始内容的整理和总结。

0
0 Comments

问题的出现原因是在处理大量的csv文件时,需要实时统计每一列中出现的次数。然而,由于csv文件的大小和数量可能非常庞大,使用传统的方法在内存中加载和处理数据可能会导致内存不足或运行时间过长。

为了解决这个问题,作者尝试将csv文件转换为一个SQL数据库,其中每个文件表示一个表。这样一来,可以使用SQL查询来实现在单个列中的搜索,并且数据库引擎会自动进行内存优化。作者建议使用Python中的sqlite3库来实现这个功能。

作者认为这是一种长远来看最好的解决方法,因为它可以显著减少负载和运行时间。如果以上的解决方法不够快速的话,可以尝试将csv文件转换为SQL数据库来处理。

需要注意的是,如果只需要对每个输入统计一次id的个数,那么这种方法可能会比较慢,因为sqlite3仍然需要先读取CSV数据并构建索引。

将csv文件转换为SQL数据库是处理大量csv文件并实时统计列出现次数的一种有效解决方法。通过使用sqlite3库,可以实现内存优化和快速的查询操作。

0