我想将硬盘上的大型Fortran记录(12G)映射到numpy数组.(映射而不是加载以节省内存.)
存储在fortran记录中的数据不是连续的,因为它除以记录标记.记录结构为"标记,数据,标记,数据,......,数据,标记".数据区域和标记的长度是已知的.
标记之间的数据长度不是4个字节的倍数,否则我可以将每个数据区域映射到数组.
可以通过在memmap中设置偏移来跳过第一个标记,是否可以跳过其他标记并将数据映射到数组?
为可能的模糊表达道歉并感谢任何解决方案或建议.
5月15日编辑
这些是fortran无格式文件.存储在记录中的数据是(1024 ^ 3)*3 float32数组(12Gb).
大小超过2千兆字节的可变长度记录的记录布局如下所示:
(有关详细信息,请参阅此处 - > [记录类型] - > [可变长度记录]部分.)
在我的情况下,除了最后一个,每个子记录的长度为2147483639字节,相隔8个字节(如上图所示,前一个子记录的结束标记和后一个子标记的开始标记,8个字节)总计).
我们可以看到第一个子记录以某个浮点数的前3个字节结束,第二个子记录以其余的1个字节开始,如2147483639 mod 4 = 3.
我最近遇到了对象的readinto
方法file
(在Python 2.7中),它类似于fread
C语言.在某些情况下它似乎很方便和强大.我计划使用它将几个文件读入一个预先分配的numpy数组,而不复制数据.
例如
a = np.empty(N)
b = memoryview(a)
fp1.readinto(b[0:100])
fp2.readinto(b[100:200])
Run Code Online (Sandbox Code Playgroud)
和
fp1.readinto(b[0:100])
fp1.seek(400, 1)
fp1.readinto(b[100:200])
Run Code Online (Sandbox Code Playgroud)
我已经使用Cython
并fread
要做到这一点我见面之前readinto
.所以我很高兴知道一个纯粹的python解决方案.
但是它的文档字符串说,
file.readinto?
Type: method_descriptor
String form: <method 'readinto' of 'file' objects>
Namespace: Python builtin
Docstring: readinto() -> Undocumented. Don't use this; it may go away.
Run Code Online (Sandbox Code Playgroud)
不要用这个?发生了什么事?
所以我很困惑,我应该使用readinto
与否?它可能导致任何不必要的问题?
是否有上述代码的替代实现,readinto
但也避免数据复制?(避免复制意味着np.concatenate
或np.stack
不是一个好的选择.)
欢迎任何建议!谢谢.
------- ------- upate
似乎我可以io.FileIO
在标准库中使用而不是内置函数open
.它看起来不错,所以我发布它作为答案.
任何评论或其他解决方案仍然欢迎! …
我有一个名为Python包a
带有两个文件__init__.py
和b
.
a/
a/__init__.py
a/b.py
Run Code Online (Sandbox Code Playgroud)
文件内容:
# a/__init__.py
from .b import *
Run Code Online (Sandbox Code Playgroud)
和
# a/b.py
c = 1
Run Code Online (Sandbox Code Playgroud)
当我a
在Python中导入时,为什么我可以a.b
直接使用?我很困惑,因为我没有b
明确导入a/__init__.py
.
如果我使用空 a/__init__.py
,那么b
在a
命名空间中没有.所以它似乎from .b import *
(或from .b import c
)也是重要的b
,为什么?
我已经检查了Python文档和SO中的几个帖子,但没有找到相关问题.
我想要所有的东西,b
但不是b
自己a
,然后我可以修改a/__init__.py
为
# a/__init__.py
from .b import *
del b
Run Code Online (Sandbox Code Playgroud)
这个好吗?
str.format
将布尔值转换为字符串的等效方法是什么?
>>> "%5s" % True
' True'
>>> "%5s" % False
'False'
Run Code Online (Sandbox Code Playgroud)
请注意 中的空格' True'
。这始终使“True”和“False”的长度相同。
我已经检查了这篇文章中的方法:
他们中没有人能做同样的事情。
这里有几个列表:a,b等我想分别对它们进行一些更改,但我对for循环的行为感到困惑.
例如:如果我们这样做
a, b = range(5), range(5,10)
for x in [a, b]: x += [0]
print(a,b)
Run Code Online (Sandbox Code Playgroud)
我们得到
([0, 1, 2, 3, 4, 0], [5, 6, 7, 8, 9, 0])
Run Code Online (Sandbox Code Playgroud)
a,b被修改.
但如果我们这样做
a, b = range(5), range(5,10)
for x in [a, b]: x = x + [0]
print(a,b)
Run Code Online (Sandbox Code Playgroud)
我们得到
([0, 1, 2, 3, 4], [5, 6, 7, 8, 9])
Run Code Online (Sandbox Code Playgroud)
a,b未被修改.我很困惑,x和a之间的关系是什么?我何时或如何修改a的值?顺便说一句,a + = b和a = a + b之间有什么区别?
无论如何,我找到了一个我们可以这样做的解决方案
a, b = range(5), range(5,10)
lis = [a, b]
for i, x in …
Run Code Online (Sandbox Code Playgroud)