fvecs及ivecs数据格式介绍(附读取代码)

最近在做关于结构化及非结构化数据混合索引及搜索的工作,其中有一项挑战是根据论文中的数据集、标签集,自己得到真值集(不知道为啥论文没给出真值集),然后进行后续工作。

在此过程中,我需要知道真值集的存储格式——ivecs。

 

ivecs与fvecs格式

在常用的公开数据集中(如CrawlEnron),数据集文件、查询文件往往使用fvecs格式存储。而真值集(即查询的答案)文件使用ivecs格式存储。其实这两种格式十分相似。

fvecs

数据集、查询集采用fvecs格式,其实他们是完全相同的东西。在数据集中,存储的是所有向量,而查询集中,存储的同样是向量,只是向量数量会少一些。

fvecs采用二进制来存储,直接打开便是乱码。

下面用一张图来表示fvecs的大致格式:

 

每一“行”中,第一个数表示数据的维度dim,后面跟着的dim个数便是向量各维度的值。(注:fvecs中的f指float32)

因此,一“行”表示的便是一个向量。

那么行数是如何计算的呢?我们一般使用下面的式子:

line_num = filesize / (dim + 1 ) / 4

其中line_num是行数,filesize是文件字节数,dim+1指每个向量占用的数值个数,4指每4个字节存储一个数值。

ivecs

ivecs其实和fvecs的格式是一样的,只不过它存储的不是向量,而是每一条查询的答案。

就是说,ivecs里的每一“行”里,第一个数据是查询答案的数量n,后面n个数是答案向量的id。(注:ivecs中的i指int32)

cpp读取fvecs文件代码

先将下面的代码放入read.cpp,然后编译出read.exe

#include <fstream>
#include <vector>
#include<iostream>
using namespace std;
 
void load_ivecs_data(const char* filename,
                 std::vector<std::vector<float> >& results, unsigned &num, unsigned &dim) {
  std::ifstream in(filename, std::ios::binary);
  if (!in.is_open()) {
    std::cout << "open file error" << std::endl;
    exit(-1);
  }
  in.read((char *)&dim, 4);
  
  
  
  in.seekg(0, std::ios::end);
  std::ios::pos_type ss = in.tellg();
  size_t fsize = (size_t)ss;
  num = (unsigned)(fsize / (dim + 1) / 4);
  results.resize(num);
  for (unsigned i = 0; i < num; i++) results[i].resize(dim);
​
  in.seekg(0, std::ios::beg);
  for (size_t i = 0; i < num; i++) {
    in.seekg(4, std::ios::cur);
    in.read((char*)results[i].data(), dim * 4);
    
  }
  in.close();
}
​
​
int main(int argc, char** argv) {
  std::vector<std::vector<float> > true_load;
  unsigned dim, num;
  load_ivecs_data(argv[1], true_load, num, dim);
    std::cout << "result_num:"<< num << std::endl << "result dimension:" << dim << std::endl;
  for(size_t i = 0; i < num; i++) {
    for(size_t j = 0; j < dim; j++) {
      std::cout << true_load[i][j] << " ";
    }
    std::cout << std::endl;
  }
  std::cout << "result_num:"<< num << std::endl << "result dimension:" << dim << std::endl;
  return 0;
}

在read.exe所在目录下放置groundtruth数据集真值表文件,然后在cmd中输入:

.\read.exe .\groundtruth

结果如下:

 

补档:python读取ivecs、fvecs代码

import sys
import numpy as np

def ivecs_read(fname):
    a = np.fromfile(fname, dtype='int32')
    d = a[0]
    return a.reshape(-1, d + 1)[:, 1:].copy()

def fvecs_read(fname):
    return ivecs_read(fname).view('float32')

dataset_path = sys.argv[1]
dataset = fvecs_read(dataset_path)

代码参考:     C++读取fvecs格式数据(SIFT1M数据集的结构) | whenever (whenever5225.github.io)icon-default.png?t=N6B9https://whenever5225.github.io/2019/08/12/anns-nsg-code2/

                Python 读取 fvecs 数据集 | Ryan Li Godicon-default.png?t=N6B9https://www.ryanligod.com/2019/03/21/2019-03-21%20%E8%AF%BB%E5%8F%96%20fvecs%20%E6%95%B0%E6%8D%AE%E9%9B%86/

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xuinrz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值