在Python中处理数百万行

在Python中处理数百万行,python,csv,bigdata,time-complexity,Python,Csv,Bigdata,Time Complexity,我想在回答这个问题之前说一句,我已经对python的时间复杂度和数据结构进行了研究,这些都可以加快速度 然而,我正在努力寻找一种有效的方法来对照250万行文件检查一组值。到目前为止,我考虑的一个解决方案是使用列表理解 目前,我正试图通过以下方式处理这一问题: def getTotalVolumeByCounty(fileName, counties): values = [] with open(fileName) as csvFile: csvReader = csv.reader

我想在回答这个问题之前说一句,我已经对python的时间复杂度和数据结构进行了研究,这些都可以加快速度

然而,我正在努力寻找一种有效的方法来对照250万行文件检查一组值。到目前为止,我考虑的一个解决方案是使用列表理解

目前,我正试图通过以下方式处理这一问题:

def getTotalVolumeByCounty(fileName, counties):

values = []

with open(fileName) as csvFile:
    csvReader = csv.reader(csvFile)

    headers = next(csvReader)

    for row in csvReader:

        i = 0
        while i < len(counties):
            if row[9] == counties[i]:
                values[i] += int(row[22])
                break
return values
def getTotalVolumeByCounty(文件名,县):
值=[]
以csvFile形式打开(文件名):
csvReader=csv.reader(csvFile)
标题=下一个(csvReader)
对于csvReader中的行:
i=0
而我(县):
如果第[9]行==县[i]:
值[i]+=int(第[22]行)
打破
返回值
“传统”的方式,如果你愿意的话。将一个列表中的每个值与另一个列表中的当前值进行比较。显然,就时间复杂性而言,这是不利的


如前所述,我曾考虑过使用列表理解——但这些实际上是如何节省时间的呢?列表理解是我当前尝试的唯一选择吗?

基于OP上的评论线程,我将在这里添加一个建议

在处理大量数据时,通常更有效的方法是首先以某种方式对数据进行排序,然后使用类似于二进制搜索的方法来查找数据块

例如,您提到要将一个列表中的项目与第二个列表中的项目进行比较。为此,我将假设第一个列表(列表A)的大小较小,第二个列表(列表B)较大

如果列表B中的项目按某个键排序,例如,县名称(假设所有县都有唯一的名称),则可以使用a在县的条目块中查找随机(基本上)项目,然后根据任何给定县的条目数,您可以执行两个循环来查找上限和下限,或者在不同的键上执行另一个二进制搜索或类似搜索,通过该搜索,列表的顺序将排在原始键(例如总体积)的第二位,这将只留下与您确定的某个度量相匹配的项目列表

如果数据尚未排序,则可能值得对其进行排序,因为Heapsort或Quicksort的时间复杂度最差为O(nlogn),而二进制搜索最差为O(logn)。在列表上循环的时间复杂度可能是O(kn^k)或其他什么,如果用图形表示的话,会糟糕很多倍

至于你问题的最后一部分,列表理解只是句法上的糖分,并没有做任何特别奇妙的事情

tldr;我建议按某个唯一标识符对数据进行排序,使用现有的通用标识符,因为您可以提供一个比较函数,它可以使用该函数,并且您可能可以在Python中查找迭代实现。然后使用二进制搜索有效地查找项目


希望这有帮助

基于OP上的评论线程,我将在这里添加一个建议

在处理大量数据时,通常更有效的方法是首先以某种方式对数据进行排序,然后使用类似于二进制搜索的方法来查找数据块

例如,您提到要将一个列表中的项目与第二个列表中的项目进行比较。为此,我将假设第一个列表(列表A)的大小较小,第二个列表(列表B)较大

如果列表B中的项目按某个键排序,例如,县名称(假设所有县都有唯一的名称),则可以使用a在县的条目块中查找随机(基本上)项目,然后根据任何给定县的条目数,您可以执行两个循环来查找上限和下限,或者在不同的键上执行另一个二进制搜索或类似搜索,通过该搜索,列表的顺序将排在原始键(例如总体积)的第二位,这将只留下与您确定的某个度量相匹配的项目列表

如果数据尚未排序,则可能值得对其进行排序,因为Heapsort或Quicksort的时间复杂度最差为O(nlogn),而二进制搜索最差为O(logn)。在列表上循环的时间复杂度可能是O(kn^k)或其他什么,如果用图形表示的话,会糟糕很多倍

至于你问题的最后一部分,列表理解只是句法上的糖分,并没有做任何特别奇妙的事情

tldr;我建议按某个唯一标识符对数据进行排序,使用现有的通用标识符,因为您可以提供一个比较函数,它可以使用该函数,并且您可能可以在Python中查找迭代实现。然后使用二进制搜索有效地查找项目


希望这有帮助

完全基于您的功能名称及其签名,我假设您只是试图按国家对总销售额进行分组,其中
国家是您感兴趣的国家的列表。Python中最直接的方法是使用计数的
dict
。分组通常使用
dict
对象进行。在这种情况下,您的
dict
也将用作“set”,因为我们将为每个国家的dict初始化
0
。然后,在增加相应的值之前,只需检查国家/地区是否在dict中

def get_total_volume_by_country(file_name, counties):
    volume_by_country = dict.fromkeys(countries, 0)
    with open(file_name) as csv_file:
        csv_reader = csv.reader(csv_file)
        headers = next(csv_reader)

        for row in csv_reader:
            country = row[9] # presumably country name
            if country in volume_by_country:
                volume_by_country[country] += int(row[22]) # volume presumably
    return volume_by_country

完全基于函数名及其签名,我假设您只是试图按国家对总销售量进行分组,其中
国家
是您感兴趣的国家的列表。Python中最直接的方法是使用计数的
dict
。分组通常使用
dict
对象进行。在本例中,您的
dict
也将用作“set”,因为我们将初始化
def get_total_volume_by_county(file_name, counties):
    county_volume_map = {county: 0 for county in counties}

    with open(file_name) as csv:
        csv_reader = csv.reader(csv)

        headers = next(csv_reader)

        for row in csv_reader:
            county_volume_map[row[9]] += row[22]

    return county_volume_map