我需要创建一个可以在速度和效率非常重要的应用程序中使用的查找表。该表将存储时间值,这些时间值以对数方式分布,以便每个数量级具有相同数量的时间步长。每个时间值将指向具有与它们相关联的强度值的波长值阵列。所以像这样:
t lambda I
0.0001 -> 0.01 -> 100
. 0.02 -> 300
. . .
. . .
. .
0.0002 -> 0.01 -> 200
. 0.02 -> 400
. . .
. . .
. .
等...
某些C代码中的函数将按时间和波长传递,并从表中查找相应的强度。生成正确强度所需的功能非常费力,所以这就是我选择使用查找表的原因。我希望将查找表写入二进制文件,因为此文件将在计算群集上的许多节点上加载进出RAM。由于我不熟悉查找表,我想知道什么是最好的(如最快/最有效)方式来实现它。
另外,是否可以从python中创建的数据结构中编写二进制文件,然后可以在C中读取?这在我的特定应用程序中非常有用,因为我已经与一些python代码连接以生成表的值。
答案 0 :(得分:2)
您可以使用struct
module,尤其是struct.pack
将Python数据转换为一串二进制数据,然后您可以将其写入文件。
访问数据的最有效方式取决于具体细节。如果对所有时间值使用相同范围的lambda值并且时间间隔始终相同,则知道每个t的强度数组的长度。在这种情况下,你可以说例如。
offset = ((time - 0.001)/0.001 * amount_of_intensities + (lambda - 0.01)/0.01)
然后使用该偏移量来创建指针。这假设您已将二进制文件读入内存并为其创建了正确类型的指针。
一个例子(在IPython中):
In [1]: import numpy as np
In [2]: data = np.random.random(20)
In [3]: data
Out[3]:
array([ 0.40184104, 0.60411243, 0.52083848, 0.50300288, 0.14613242,
0.39876911, 0.16157968, 0.70979254, 0.65662686, 0.14884378,
0.65650842, 0.40906677, 0.3027295 , 0.26070303, 0.82051509,
0.96337179, 0.34622595, 0.08532211, 0.65079174, 0.68009011])
In [4]: import struct
In [5]: struct.pack('{}d'.format(len(data)), *data)
Out[5]: 'f\xf9\x80y\xc3\xb7\xd9?\xe2x\x92\x99\xe3T\xe3?0vCt\xb5\xaa\xe0?7\xfcJ|\x99\x18\xe0?X\xf5l\x8ew\xb4\xc2?b\x9c\xd1\xden\x85\xd9?\xc4\x0c\xad\x9d\xa4\xae\xc4?\xae\xc3\xbe\xd7\x9e\xb6\xe6?\xd5\xf3\xebV\x16\x03\xe5?\x14J\x9a$P\r\xc3?p\xd4t\xf3\x1d\x02\xe5?\xfe\tUg&.\xda?\xf4hV\x91\xeb_\xd3?@FL\xc0[\xaf\xd0?$\xbe\x08\xda\xa8A\xea?\xf3\x93\xcb\x11\xf1\xd3\xee?\xce\x9e\xd9\xe7\x90(\xd6?\x10\xd2\x12c\xab\xd7\xb5?f\xac\x124I\xd3\xe4?}\x95\x1cSL\xc3\xe5?'
为方便起见,我使用了numpy模块。它可以与浮点数列表一起使用。
从内到外分析最后一行。格式表达式给出:
In [9]: '{}d'.format(len(data))
Out[9]: '20d'
这意味着我们想要创建一个包含20 d
个值的字符串。对于IEEE 754双宽度浮点数,d
是format character。
所以我们真正拥有的是;
struct.pack('20d', *data)
*
之前的data
- 运算符意味着"解压缩此列表"。
请注意,二进制数通常不能在不同的硬件平台之间移植(例如intel x86和ARM)。
一旦你拥有了这么大的二进制数,你就可以把它写成一个文件。
在C中,打开文件并将整个内容读入内存块。然后在该记忆块的开头做一个正确类型的指针,你就可以了。