最合适的数据结构(Python)
Posted
技术标签:
【中文标题】最合适的数据结构(Python)【英文标题】:Most appropriate data structure (Python) 【发布时间】:2011-05-09 00:52:33 【问题描述】:我是 Python 新手,对于在我的代码中存储数据的“最佳”方式可能是一个非常基本的问题。非常感谢任何建议!
我有一个长长的 .csv 文件,格式如下:
Scenario,Year,Month,Value
1,1961,1,0.5
1,1961,2,0.7
1,1961,3,0.2
etc.
我的场景值从 1 到 100,年份从 1961 到 1990,月份从 1 到 12。因此,我的文件有 100*29*12 = 34800 行,每行都有一个关联的值。
我想将此文件读入某种 Python 数据结构,以便我可以通过指定“场景”、“年”和“月”来访问“值”。请问最好的方法是什么(或者有哪些不同的选择)?
在我的脑海中,我认为这些数据是一种“数字长方体”,带有用于场景、年和月的轴,因此每个值都位于坐标(场景、年、月)。出于这个原因,我很想尝试将这些值读入 3D numpy 数组并使用 Scenario、Year 和 Month 作为索引。这是明智的做法吗?
我想我也可以制作一个字典,其中的键类似于
str(Scenario)+str(Year)+str(Month)
这样会更好吗?还有其他选择吗?
(“更好”我想我的意思是“访问速度更快”,尽管如果一种方法比另一种方法占用更少的内存,那么了解这一点也很好)。
非常感谢!
【问题讨论】:
哇——多么棒的网站! 5 个人在比我写原始问题还短的时间内给了我很好的答案。谢谢! 【参考方案1】:我会使用sqlite3 将数据存储到磁盘。您将能够通过 SQL 查询读取完整的数据集或子集。然后,您可以将该数据加载到一个 numpy 数组或其他 Python 数据结构中——无论是最方便的任务。
如果您确实选择使用 sqlite,还请注意 sqlite 具有 TIMESTAMP 数据类型。
将年份和月份合并到一个 TIMESTAMP 中可能是个好主意。当您将 TIMESTAMP 读入 Python 时,可以告诉 sqlite3
自动将 TIMESTAMP 转换为 datetime.datetime
对象,这将减少您必须编写的一些样板代码。它还将更容易形成查询两个日期之间所有行的 SQL 查询。
【讨论】:
干杯 unutbu,这听起来是个不错的选择。我会做一些阅读,看看它是否在我目前的能力范围内。同时,我将使用 fmark 的建议。 @JamesS:没问题。欢迎来到 SO!【参考方案2】:按照你描述的那样制作一本字典。如果您需要将数据作为数字,请在读取它们并将数字存储在字典中时将它们转换为数字一次。使用字符串作为键会更快。如果需要代码方面的帮助,请告诉我。
【讨论】:
【参考方案3】:如果您每次要通过不同的参数访问您的值,sqlite 是一个不错的选择。
如果不是这样,并且您将始终按此三元组(场景、年、月)访问,则可以使用元组(不可变列表)作为键,将值作为值。
在代码中它看起来像:
d =
d[1, 1961, 12] = 0.5
或更通用的循环代码:
d[scenario, year, month] = value
稍后您可以通过以下方式访问它:
print d[scenario, year, month]
Python 会自动为你创建元组。
【讨论】:
【参考方案4】:我会使用元组的字典。简单、快速和哈希表查找来检索单个值:
import csv
reader = csv.reader(open('data.csv', 'rb'))
header = reader.next()
data =
for row in reader:
key = tuple([int(v) for v in row[:-1]])
val = row[-1]
data[key] = float(val)
# Retrieve a value
print data[1, 1961, 3]
【讨论】:
感谢 fmark。我复制并粘贴了您的代码,效果非常好。我没想到有人会为我编写代码,但你还是这样做了 :-) 用python写一个简单的解决方案总是一种乐趣:)以上是关于最合适的数据结构(Python)的主要内容,如果未能解决你的问题,请参考以下文章