我有一个数据集,其格式为我想要循环的dicts列表,并根据与另一个值列表中的值的匹配来提取该数据集的子集。
我目前正在以两个单独的for x in y
循环的方式执行此操作,如下面的示例代码所示,但我确信这是非常低效的并且它需要非常高效长时间查看大型列表。
CSV格式的示例数据:
╔══════════════╦══════════════╦═══════════════╦════════════════╦══════════════════════╗
║ City ║ State ║ 2013 Estimate ║ 2013 Land Area ║ 2013 Popular Density ║
╠══════════════╬══════════════╬═══════════════╬════════════════╬══════════════════════╣
║ New York ║ New York ║ 8405837 ║ 302.6 sq mi ║ 27012 per sq mi ║
║ Los Angeles ║ California ║ 3884307 ║ 468.7 sq mi ║ 8092 per sq mi ║
║ Chicago ║ Illinois ║ 2718782 ║ 227.6 sq mi ║ 11842 per sq mi ║
║ Houston ║ Texas ║ 2195914 ║ 599.6 sq mi ║ 3501 per sq mi ║
║ Philadelphia ║ Pennsylvania ║ 1,553,165 ║ 134.1 sq mi ║ 11379 per sq mi ║
║ Phoenix ║ Arizona ║ 1513367 ║ 516.7 sq mi ║ 2798 per sq mi ║
║ San Antonio ║ Texas ║ 1409019 ║ 460.9 sq mi ║ 2880 per sq mi ║
║ San Diego ║ California ║ 1355896 ║ 325.2 sq mi ║ 4020 per sq mi ║
║ Dallas ║ Texas ║ 1257676 ║ 340.5 sq mi ║ 3518 per sq mi ║
║ San Jose ║ California ║ 998537 ║ 176.5 sq mi ║ 5359 per sq mi ║
╚══════════════╩══════════════╩═══════════════╩════════════════╩══════════════════════╝
示例代码
#read data into list of dicts
import csv
with open('data.csv', 'rb') as csv_file:
data = list(csv.DictReader(csv_file))
# cities of interest to extract from larger data
int_cities = [['New York'],['Houston'],['Pheonix'],['San Jose']]
# loop through data and look for match in data['City'] and interest_cities, append match to int_cities_data
int_cities_data = []
for i in data:
for u in int_cities:
if i['City'] == u:
int_cities_data.append(i)
正如我所说,这当前有效,但是当我必须在data
中遍历~2M行并查看int_cities
中另外50k行的匹配时,需要很长时间。
如何提高效率?
我忘了数据太大而无法使用csv.DictReader
所以我一直使用以下内容将我的数据读入一个dicts列表(删除标题后):
这是未经测试的
header = ['City','State','2013 Estimate','2013 Land Area','2013 Popular Density']
data = [{key: value for (key, value) in zip(header, line.strip().split(','))} for line in open('data.csv') if line['City'] in int_cities]
我尝试修改上面的代码,用于将数据加载到dicts列表中,而不使用csv.DictReader
。
答案 0 :(得分:4)
不是将文件中的所有数据都读入列表,而是遍历该列表以搜索所需的城市,一次迭代csv文件一行,并且只有在项目列表中才添加项目。重新关注你关心的城市。这样你就不需要将整个文件存储在内存中了,你不需要迭代两次(一次构建完整的列表,然后再次将你关心的条目拉出来)。
此外,请将您关注的城市存储在set
而不是list
,这样您就可以在O(1)
时间而不是O(n)
进行查找。如果你进行大量的查找(这听起来像你),这可能会大大提高性能。
#read data into list of dicts
import csv
int_cities = set(['New York', 'Houston', 'Phoenix', 'San Jose'])
int_cities_data = []
with open('data.csv', 'rb') as csv_file:
for line in csv.DictReader(csv_file):
if line['City'] in int_cities:
int_cities_data.append(line)
或者作为列表理解:
with open('data.csv', 'rb') as csv_file:
int_cities_data = [line for line in csv.DictReader(csv_file) if line['City'] in int_cities]