我使用
将numpy 2维浮点数组写成二进制文件 narr.tofile(open(filename,"wb"),sep="",format='f')
并尝试使用
在c中检索相同内容FILE* fin = fopen(filename,"rb")
float* data = malloc(rows*2*sizeof(float));
fread(data, sizeof(float), rows*2, fin);
打印时此数据数组显示的值与原始数组不同。我错过了什么吗? 感谢
答案 0 :(得分:0)
这可能取决于您使用的系统,小端的ndarray.tofile()
输出,这意味着最低有效字节先存储,尝试使用numpy.byteswap()
和然后转换为文件。也尝试在没有格式说明符的情况下执行此操作并查看结果。文档说明说明符的默认值为format="%s"
,尝试在格式说明符之前放置百分比符号,如%f
。
答案 1 :(得分:0)
如果您通过np.save('foo.npy',narr)
以npy格式保存数据,这是另一种方法。它是2D npy文件的(编写器和读取器),它将数据作为二维特征矩阵返回。请注意,代码执行了许多假设,仅适用于使用标准np save()选项保存的2D数组。
// npymatrix.h
#ifndef NPYMATRIX_H
#define NPYMATRIX_H
#include <Eigen/Eigen>
// Routines for saving and loading Eigen matrices as npy files.
int npywrite(Eigen::MatrixXd& mat, const char *filename, bool do_flip_y);
int npyread(const char *filename,
// output
Eigen::MatrixXd& mat);
#endif /* NPYMATRIX */
和C ++文件:
// npymatrix.cc
#include <stdio.h>
#include <string.h>
#include "npymatrix.h"
using namespace Eigen;
enum {
FLOAT8,
FLOAT4,
INT8
};
static const int data_size[] = {8,4, 1};
int npywrite(MatrixXd& mat, const char *filename, bool do_flip_y)
{
FILE *fh = fopen(filename, "wb");
if (!fh)
return -1;
// Write header and version number to file
fwrite("\223NUMPY"
"\001\000"
, 1, 8, fh);
char header[100];
sprintf(header,
"{'descr': '<f8', 'fortran_order': False, 'shape': (%d, %d), } \n",
mat.rows(),
mat.cols());
unsigned short header_len = strlen(header);
fwrite(&header_len, 2, 1, fh);
fwrite(header, header_len, 1, fh);
// Is there a faster way??
for (int row_idx=0; row_idx<mat.rows(); row_idx++) {
for (int col_idx=0; col_idx<mat.cols(); col_idx++) {
int r_idx = row_idx;
if (do_flip_y)
r_idx = mat.rows()-1-r_idx;
double v = mat(r_idx, col_idx);
fwrite(&v, sizeof(double), 1, fh);
}
}
fclose(fh);
return 0;
}
static const char *find_next_alphanum(const char *p)
{
while(*p && (!isalnum(*p)))
p++;
return p;
}
static const char *find_next_string_after(const char *p, const char *token)
{
p = strstr(p, token);
if (!p)
return p;
return p + strlen(token);
}
static const char *find_next_alnum_after(const char *p)
{
while(*p and isalnum(*p))
p++;
return p;
}
static char *strdup_to_delim(const char *p, const char *delim)
{
const char *pstart = p;
while(*p && !strchr(delim, *p))
p++;
return strndup(pstart, p-pstart);
}
int npyread(const char *filename,
// output
MatrixXd& mat)
{
FILE *fh = fopen(filename, "rb");
// Magic bytes
char magic_bytes[6], version[2];
fread(magic_bytes, 1, 6, fh);
// Version
fread(version, 1, 2, fh);
// Header len
short header_len;
fread(&header_len, 1, 2, fh);
// Read the header
char *header = new char[header_len];
fread(header, 1, header_len, fh);
// parse the header. This is ugly but works for a standard header...
const char *p = header;
p = find_next_string_after(p, "descr");
p = find_next_alphanum(p+1);
char *descr = strdup_to_delim(p, "'\"");
p = find_next_string_after(p, "fortran_order");
p = find_next_alphanum(p+1);
char *fortran_order = strdup_to_delim(p, ",");
p = find_next_string_after(p, "shape");
p = find_next_alphanum(p+1);
char *shape = strdup_to_delim(p, ")");
int height = atoi(shape);
int width = atoi(find_next_alphanum(find_next_alnum_after(shape)));
// Decode the type
int dtype=-1;
if (strcmp("<f8", descr)==0
|| strcmp("f8", descr)==0
) {
dtype=FLOAT8;
}
else if (strcmp("<f4", descr)==0
|| strcmp("f4", descr)==0) {
dtype=FLOAT4;
}
else {
printf("Unsupported data type: %s!\n", descr);
return -1;
}
int pixel_size = data_size[dtype];
mat.setZero(height, width);
for (int row_idx=0; row_idx<height; row_idx++) {
for (int col_idx=0; col_idx<width; col_idx++) {
unsigned char v[8];
double gl;
fread(v, 1, pixel_size, fh);
switch(dtype) {
case FLOAT8:
gl = *((double*)v);
break;
case FLOAT4:
gl = *((float*)v);
break;
default:
gl = *((unsigned char*)v);
break;
}
mat(row_idx,col_idx) = gl;
}
}
fclose(fh);
free(shape);
free(descr);
free(fortran_order);
delete [] header;
return 0;
}