在python中存储大量数据

在python中存储大量数据,python,Python,也许我会为我的问题做一个小的介绍。我正在编写一个python程序,用于不同物理模拟的后处理。每个模拟可以创建高达100 GB的输出。我处理不同时间步长的不同信息(如位置、场和密度等)。我想一次访问所有这些数据,这是不可能的,因为我的系统没有足够的内存。通常我使用读取文件,然后执行一些操作并清除内存。然后我读取其他数据,进行一些操作,并清除内存 现在是我的问题。如果我这样做,那么我会花很多时间不止一次地读取数据。这需要很多时间。我只想阅读一次,并将其存储起来,以便于访问。你知道一种存储大量数据的方

也许我会为我的问题做一个小的介绍。我正在编写一个python程序,用于不同物理模拟的后处理。每个模拟可以创建高达100 GB的输出。我处理不同时间步长的不同信息(如位置、场和密度等)。我想一次访问所有这些数据,这是不可能的,因为我的系统没有足够的内存。通常我使用读取文件,然后执行一些操作并清除内存。然后我读取其他数据,进行一些操作,并清除内存

现在是我的问题。如果我这样做,那么我会花很多时间不止一次地读取数据。这需要很多时间。我只想阅读一次,并将其存储起来,以便于访问。你知道一种存储大量数据的方法吗?这种方法非常快,或者不需要很大的空间

我刚刚创建了一个方法,它比普通的开放读取快十倍左右。但是我使用了
cat
(linux命令)来实现这一点。这是一个非常肮脏的方法,我想把它从我的脚本中踢出去

是否可以使用数据库存储这些数据,并以比正常读取更快的速度获取数据?(很抱歉问这个问题,但我不是一名计算机科学家,我对数据库也不太了解)

编辑:

我的cat代码如下所示-仅举一个例子:

out = string.split(os.popen("cat "+base+"phs/phs01_00023_"+time).read())
# and if I want to have this data as arrays then I normally use and reshape (if I
# need it)
out = array(out)
out = reshape(out)
通常我会使用numpy方法
numpy.loadtxt
,它需要与正常读取相同的时间:

f = open('filename')
f.read()
...
我认为,
loadtxt
只需使用一些附加代码行的常规方法即可


我知道有一些更好的方法来读取数据。但我发现的一切都很慢。现在我将尝试
mmap
,希望我能有更好的表现

如果您使用的是大型数据集,Python可能不是最佳选择。如果你想使用MySQL或Postgres这样的数据库,你应该试一试。它使使用小型Python对象处理潜在的大型数据集变得非常容易。例如,如果使用如下定义:

from datetime import datetime
from sqlalchemy import Column, DateTime, Enum, ForeignKey, Integer, \
    MetaData, PickleType, String, Text, Table, LargeBinary
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import column_property, deferred, object_session, \
    relation, backref

SqlaBaseClass = declarative_base()

class MyDataObject(SqlaBaseClass):
  __tablename__ = 'datarows'
  eltid         = Column(Integer, primary_key=True)
  name          = Column(String(50, convert_unicode=True), nullable=False, unique=True, index=True)
  created       = Column(DateTime)
  updated       = Column(DateTime, default=datetime.today)

  mylargecontent = deferred(Column(LargeBinary))

  def __init__(self, name):
      self.name    = name
      self.created = datetime.today()

  def __repr__(self):
      return "<MyDataObject name='%s'>" %(self.name,)

我想重点是:您可以向数据中添加任意多的字段,根据需要添加索引以加快搜索速度。而且,最重要的是,当您使用
MyDataObject
时,您可以使潜在的大字段
延迟
,以便仅在需要时加载它们

我会尝试使用。有两个常用的Python接口,和。虽然后者似乎更为广泛,但我更喜欢前者。

如果您使用的是64位操作系统,则可以使用该模块将整个文件映射到内存空间。然后,由于操作系统负责管理您的访问模式,读取数据的随机位可以更快地完成。请注意,您实际上不需要100 GB的RAM来实现这一点,因为操作系统将在虚拟内存中管理所有内存


我在64位FreeBSD 8上使用了一个30 GB的文件(Wikipedia XML文章转储),效果非常好。

您能编辑您的问题以包含更具体的要求吗?什么样的手术?您需要一次操作多少数据集?操作是流式的还是需要内存中的完整子集?您的cat方法和开放阅读方法是什么?(有时小细节真的会让事情慢下来)“这真是一种肮脏的方法”?这是什么意思?它有效,对吗?什么使它“脏”?也许您应该包括这方面的代码。在100GB的容量下,您可能需要其他类型的数据存储/数据库。无论是东京内阁、mongodb、redis、sqlite还是postgresql。这都是一个权衡的问题,你可能是唯一一个能决定你真正需要什么的人。我认为它在Windows上不起作用。我从未测试过它,因为我身边没有任何Windows机器。+1对于Python注释,我认为这不是一个高负载软件的好选择。-1对于Python注释,科学Python用户一直在处理大型数据集time@olokki“Python可能不是你最好的选择”我不认为这是一个充满争议的说法,我的回答的其余部分确实解决了如何使用Python的原始问题。感谢您的解决方案。对于这种情况,我需要HDF5格式的数据,或者?我的模拟结果采用标准FORTRAN格式。如果我理解正确,那么我可以使用FORTRAN API。但我不想更改FORTRAN代码。我没有写模拟代码,它也不是我的。也许我可以将普通数据(读取后)更改为HDF5。编写一个转换器读取数据并以HDF5格式写入数据应该相当容易——如果数据的结构不太复杂,在几行Python代码中就可以做到这一点。但也许你可以先试试格雷格关于使用mmap的建议——如果这对你有效,那就更容易了。
# set up database connection; open dbsession; ... 

for elt in dbsession.query(MyDataObject).all():
    print elt.eltid # does not access mylargecontent

    if (something(elt)):
        process(elt.mylargecontent) # now large binary is pulled from db server
                                    # on demand