这个pyhton2和python3不兼容实在是太要命了!!!血坑!!!
安装
- pip install pyflann
- conda install numpy
适配
网上有很多方法是这样的:
sudo 2to3 -w [pyflann directory in dist-packages]
但是我在实际操作中还是不行,但是也有人是成功的
flann不能运行的原因其实主要分成两大类,一类是因为文件导入错误,另一类是因为 python2 中的语法在 python3 中不适配!
一、修改导入规则
1.1 错误概况
类似于 ModuleNotFoundError: No module named 'xxxxx'
的错误都是因为导入方式不对,需要修改导入规则,大部分是将 from xxx import *
改为 from .xxx import *
,也有部分例外,会在下面说明。
1.2 涉及到的文件
-
__init__.py
改为: -
index.py
改为: -
bindings\__init__.py
改为: -
io\__init__.py
改为: -
io\dataset.py
改为: 将 31-33 行改为from . import xxxxx
的形式
二、修改语法
2.1 错误概况
类似于 SyntaxError: invalid syntax
的错误都是因为部分 python2 的语法在 python3 中是错误的,需要修改语法,大部分是将 except Exception, e
改为 except Exception as e
,也有其他的语法错误,会在下面一一说明。
2.2 涉及到的文件
-
bindings\flann_ctypes.py
改: 151 行 将except Exception, e
替换为except Exception as e
,201 行exec
语句加上括号,53 、78 行 将dict.iteritems()
替换为dict.items()
结果如下:
-
io\dataset.py
改: 61 行 将except Exception, e
替换为except Exception as e
结果如下:
-
io\hdf5_dataset.py
改: 34、67、85 行 将except Exception, e
替换为except Exception as e
结果如下:
三、使用
3.1 建立 Flann 并测试使用
###python3
import pyflann
import pickle
import numpy as np
# 生成数据
train_n = 100000
test_n = 500
feature_number = 500
train_data = np.random.rand(train_n, feature_number)
test_data = np.random.rand(test_n, feature_number)
# 设置distance type
pyflann.set_distance_type("euclidean")
# 建立FLANN类
flann = pyflann.FLANN()
# 建立索引并分类
branching = 10
params = flann.build_index(train_data, algorithm='kmeans',target_precision=0.9, branching = branching , log_level='info')
# 测试
top_k_results = 20
# sims: 500 * 20 每行代表一个test data,第k列是对应test data的TOP-k 结果
# dists: 500 * 20 每行代表一个test data, 第k列是test data 和 top-k result 的距离
sims, dists = flann.nn_index(test_data, top_k_results, checks = params['checks'])
# 保存
pickle.dump(params,open('params.pk','wb'))
flann.save_index(b'flann_index')
# Or
# flann_filename = 'flann_index'
# flann.save_index(bytes(flann_filename, encoding='utf8'))
3.2 读取已经建立好的 FLANN,并使用
import pickle
import pyflann
import numpy as np
# 读取上次的train_data
train_data = np.load(...)
# 从文件读取 flann
pyflann.set_distance_type("euclidean")
flann = pyflann.FLANN()
params = pickle.load(open('params.pk','rb'))
flann.load_index(b'flann_index', train_data)
# Or
# flann_filename = 'flann_index'
# flann.load_index(bytes(flann_filename, encoding='utf8'), train_data)
# 使用
newData = np.random.rand(200,500)
topk = 20
sims, dists = flann.nn_index(newData, topk, checks=params['checks'])
参考
[1] https://blog.csdn.net/qq_28824831/article/details/85003851
[2] https://blog.csdn.net/zhaojizhinex/article/details/104894344
[3] https://download.csdn.net/download/Wolf_xujie/18940725