用python制作查找表,写入可在C程序中读取的二进制文件

用python制作查找表,写入可在C程序中读取的二进制文件,python,c,binaryfiles,lookup-tables,Python,C,Binaryfiles,Lookup Tables,我需要创建一个查找表,可以在速度和效率非常重要的应用程序中使用。该表将存储对数分布的时间值,以便每个数量级具有相等数量的时间步长。每个时间值将指向一组波长值,这些波长值具有与其关联的强度值。比如说: t lambda I 0.0001 -> 0.01 -> 100 . 0.02 -> 300 . . . .

我需要创建一个查找表,可以在速度和效率非常重要的应用程序中使用。该表将存储对数分布的时间值,以便每个数量级具有相等数量的时间步长。每个时间值将指向一组波长值,这些波长值具有与其关联的强度值。比如说:

   t         lambda           I
0.0001 ->     0.01     ->    100
   .          0.02     ->    300
   .            .             .
   .            .             .
                .             .
0.0002 ->     0.01     ->    200
   .          0.02     ->    400
   .            .             .
   .            .             .
                .             .
等等

一些C代码中的函数将被传递一个时间和波长,并从表中查找相应的强度。生成正确强度所需的函数非常繁重,因此我选择使用查找表。我希望将查找表写入一个二进制文件,因为这个文件将在计算集群上的许多节点上的RAM中加载和加载。由于我不熟悉查找表,我想知道实现这一点的最佳方式(如最快/最有效的方式)是什么

另外,是否可以从用python创建的数据结构中写入二进制文件,然后用C读取?这在我的特定应用程序中非常有用,因为我已经在与一些python代码交互以生成表的值。

您可以使用,尤其是
struct.pack
将python数据转换为二进制数据字符串,然后将其写入文件

访问数据的最有效方式取决于具体情况。如果对所有时间值使用相同范围的lambda值,并且时间间隔始终相同,则可以知道每个t的强度数组的长度。在那种情况下,你可以说

offset = ((time - 0.001)/0.001 * amount_of_intensities + (lambda - 0.01)/0.01)
然后使用该偏移量创建指针。这假设您已将二进制文件读入内存,并创建了指向该文件的正确类型的指针

例如(在IPython中):

我使用numpy模块是为了方便。它同样适用于浮点数列表

从内到外分析最后一行。格式表达式给出:

In [9]: '{}d'.format(len(data))
Out[9]: '20d'
这意味着我们要生成一个由20个
d
值组成的字符串。
d
是IEEE 754双宽度浮点数的首选项

所以我们真正拥有的是

struct.pack('20d', *data)
*
-运算符在
数据之前表示“解包此列表”

请注意,二进制数通常不能在不同的硬件平台(如intel x86和ARM)之间移植

一旦你有了这个大的二进制数数组,你就可以把它写入一个文件


在C语言中,打开文件并将整个内容读入内存块。然后做一个正确类型的指针指向内存块的开头,你就可以开始了。

关于这一点,已经有了一个更详细的答案。时间步长是对数分布的,因此每个数量级都有相等的分割数。我想这会改变一切。。。我将更新问题,以说明这一点。为了澄清上述情况,数组是否类似于以下数据=[t0,w00,i00,w01,i01,…w0n,i0n,t1,w10,i10,w11,i11,…tn,wn0,in0,wn1,…wnn,inn],其中tx是时间步长,wxy是相应的波长,ixy是相应的强度?然后使用偏移量在二进制文件中跳转一定数量的位以找到正确的数据点?@jasper如果时间步长和波长的间隔在整个范围内都是一致的,则只需存储强度。因为您可以使用公式来索引正确的强度。即查表的本质;你可以用一个简单的公式找到正确的数字。如果波长的数量或间距并非在所有时间步长上都是恒定的,那么问题就会变得复杂得多。表格是否已预计算?数值将被计算并输出到包含数据列的文本文件中,因此我需要将这些数据放入某种结构中。我想知道什么样的结构最好。。。但由于我将用python编写它并用C加载它,所以我不确定该怎么做。听起来你可以使用固定长度的行,直接在文件中读/写int/float类型。如果你在一个统一的计算集群上,那么你就不必担心大/小端或32位/64位的问题,你可以直接读取字节。当然,一旦你有了一个二进制文件,你用什么来读取它并不重要。一个文件就是一个文件就是一个文件。
struct.pack('20d', *data)