文章目录
快速计算的常见需求
给定一组实体打分,求每个实体的排名
可以直接调包:
from scipy.stats import rankdata
label_ranks = rankdata(-label_scores, method='average', axis=-1)[np.arange(label_scores.shape[0]), eid]
也可以用两次argsort!有点绕,但是很方便。
- 给定一个[实体打分]列表lsource,argsort的结果列表res里,res[i]代表的是第i小/大的[实体打分]的[source的下标x],即排名。
- 如果对res再次进行一次从小到大排序的argsort,结果res2,那么res2[i]表示的是第i小的[source的下标x]的[res的下标y]。
- 而第i小的[source的下标x],i一定等于x,所以res2[i]得到的是source的下标i的[res的下标y],即排名。
这个速度比rankdata快(可能是因为rankdata是numpy,但是上面可以在gpu上跑?A6000上差了3个数量级)
bm25
参考工作ToG,调包rank_bm25
bm25
python
Python中如何在模块搜索路径中添加自己的目录
https://blog.csdn.net/oJinGangZuan/article/details/127491532
import sys
sys.path.append('/Users/michael/my_py')
# 获取当前文件的绝对路径
current_file_path = os.path.abspath(__file__)
# 获取当前文件的上一级目录
parent_directory = os.path.dirname(current_file_path)
# 将上一级目录添加到模块搜索路径中
sys.path.append(parent_directory)
tqdm怎么设置自定义的增加
from tqdm import tqdm
import time
# 设置总值
total_iterations = 100
# 创建进度条对象,并设置总值
progress_bar = tqdm(total=total_iterations)
# 模拟一个循环,更新进度条
for i in range(total_iterations):
# 模拟一些处理时间
time.sleep(0.1)
# 更新进度条
progress_bar.update(1)
# 关闭进度条
progress_bar.close()
tqdm
代码中见到的用法:
pbar = tqdm(total=len(pos_edges))
...
pbar.n
...
pbar.update(1)
...
pbar.close()
for (str_id, datum) in tqdm(p.imap(extract_save_subgraph, args_), total=len(links)):
...操作args_里每个参数放到extract_save_subgraph后的返回值(str_id, datum)
易得主要形式是tqdm(..,total=?)
zip:组合多个元素返回一个迭代器
zip(*iterables)
如zip(range(4),range(4))
该函数将可迭代对象作为参数并返回一个迭代器。此迭代器生成一系列元组,其中包含来自每个可迭代对象的元素。zip的用法
灵活运用:grail代码:
graphs_pos, g_labels_pos, r_labels_pos, graphs_negs, g_labels_negs, r_labels_negs = map(list, zip(*samples))
samples是一个{list:2},samples[i]是一个{tuple:6}。这样处理后,graphs_pos等内容大小都是{list:2}
struct:处理二进制函数
将字节串解读为打包的二进制数据
用于处理二进制内容。
常用函数:
struct.pack(format, v1, v2, ...)
返回一个 bytes 对象,其中包含根据格式字符串 format 打包的值 v1, v2, … 参数个数必须与格式字符串所要求的值完全匹配。
struct.unpack(format, buffer)
根据格式字符串 format 从缓冲区 buffer 解包(假定是由 pack(format, …) 打包)。 结果为一个元组,即使其只包含一个条目。 缓冲区的字节大小必须匹配格式所要求的大小,如 calcsize() 所示。
struct.calcsize(format)
返回与格式字符串 format 相对应的结构的大小(亦即 pack(format, …) 所产生的字节串对象的大小)。
格式字符串的第一个字符可用于指示打包数据的字节顺序,大小和对齐方式
默认是@
,其他选择有=<>!
。具体含义可以查上面的文档链接。
注意,转换二进制数据还有其他方式,如int.from_bytes(value, byteorder='little')
。两者的不同
int.from_bytes
只返回一个单独的int对象,所以如果需要的不止int就不能用。struct.unpack
只支持fixed-length的数值C类型。而int.from_bytes
支持任意size的integers。
如果只是想要一个integer,建议用int.from_bytes
。因为struct
的主要目的是把C的struct转换为python对象。
但是并没有float.from_bytes
,所以解析float的时候还是要用struct.unpack()
scipy:矩阵压缩
压缩numpy矩阵,官网介绍:
第i列的row indices存储在indices[indptr[i]:indptr[i+1]]处
对应的值存在data[indptr[i]:indptr[i+1]]处
同理,对于csr_matrix,第i行的column indices存储在indices[indptr[i]:indptr[i+1]]处,对应的值存在data[indptr[i]:indptr[i+1]]处
举例:
1 0 0 0
0 0 0 0
0 2 3 4
5 0 6 7
from scipy.sparse import csc_matrix, csr_matrix
import numpy as np
indptr = np.array([0, 2, 3, 5, 7])
indices = np.array([0, 3, 2, 2, 3, 2, 3])
data = np.array([1, 5, 2, 3, 6, 4, 7])
csc_matrix_0 = csc_matrix((data, indices, indptr), shape=(4, 4))
print(csc_matrix_0.toarray())
indptr2 = np.array([0, 1, 1, 4, 7])
indices2 = np.array([0, 1, 2, 3, 0, 2, 3])
data2 = np.array([1, 2, 3, 4, 5, 6, 7])
csr_matrix_0 = csr_matrix((data2, indices2, indptr2), shape=(4, 4))
print(csr_matrix_0.toarray())
也可以通过csc_matrix((data, (row_ind, col_ind)), [shape=(M, N)])
格式生成压缩矩阵,其中a[row_ind[k], col_ind[k]] = data[k]
获取元素的方式:matrix[i,j]
矩阵乘法:直接*
点积:m.dot(m2)
转化为coo:
[Numpy] csr_matrix | .todense() | .tocoo() |_让我安静会的博客-CSDN博客_tocoo()函数
m.tocoo()
是把稀疏矩阵如csc_matrix m转化为coo矩阵。
too.row
是获得coo矩阵原来格式的data的行号 格式是numpy
numpy.tolist()
是把numpy array 转化为 list
接上述代码继续测试:
coo = csr_matrix_0.tocoo()
print('---------------')
print(coo)
coo_row = coo.row
print('---------------')
print(coo_row)
print(coo.col)
coo_row_list = coo_row.tolist()
print('---------------')
print(coo_row_list)
num = len(coo_row_list)
print('---------------')
print(num)
LMDB:数据库
env = lmdb.open(params.db_path, map_size=map_size, max_dbs=6)
如果train文件夹下没有params.db_path文件,则会生成一个空的,如果有,不会覆盖。
map_size定义最大储存容量,单位是kb,以下定义1TB容量
max_dbs定义了可用数据库的最大数量。 如果为 0,则假定环境将用作单个数据库
with env.begin(write=True, db=split_env) as txn:
txn.put('num_graphs'.encode(), (len(links)).to_bytes(int.bit_length(len(links)), byteorder='little'))
write=True:写入操作,默认是False。
db=split_env是要操作的默认命名数据库。 如果未指定,则默认为环境的主数据库。 可以在下面的每个调用的基础上被覆盖。
.put(key, value) 对数据库进行插入和修改操作,传入的参数为键值对。
.encode() 方法以 encoding 指定的编码格式编码字符串。errors参数可以指定不同的错误处理方案,如str.encode(encoding='UTF-8',errors='strict')
。默认编码为 ‘utf-8’。
.to_bytes()把int转化为bytes,第一个参数指定要转换的bytes占多少个字节,第二个参数byteorder 是指定大端或者是小端的,第三个参数signed参数表示这个bytes对应的是有符号的数,或者无符号的int,这个是boolean值可以不写
split_env = env.open_db(db_name_pos.encode())
打开一个环境,参数是环境名称。
multiprocessing:多进程加速
import multiprocessing as mp
代码:
with mp.Pool(processes=None, initializer=intialize_worker, initargs=(A, params, max_label_value)) as p:
args_ = zip(range(len(links)), links, g_labels)
for (str_id, datum) in tqdm(p.imap(extract_save_subgraph, args_), total=len(links)):
max_n_label['value'] = np.maximum(np.max(datum['n_labels'], axis=0), max_n_label['value'])
subgraph_sizes.append(datum['subgraph_size'])
enc_ratios.append(datum['enc_ratio'])
num_pruned_nodes.append(datum['num_pruned_nodes'])
with env.begin(write=True, db=split_env) as txn:
txn.put(str_id, serialize(datum))
mp.Pool()提供了一种快捷的方法,赋予函数并行化处理一系列输入值的能力,可以将输入数据分配给不同进程处理(数据并行)。返回一个进程池对象。
processes=
进程池的数量
initializer=
一个函数f
initargs=
函数f的参数们
for (str_id, datum) in tqdm(p.imap(extract_save_subgraph, args_), total=len(links)):
其中p.imap()
用法类似用法
上述代码中,args_
迭代的每一个参数是extract_save_subgraph的参数。
C++
mingw安装
msys2安装
msys2安装toolchain:pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain