当前位置: 首页 > 面试题库 >

多维索引和线性索引之间的大量转换

孟和玉
2023-03-14
问题内容

我正在寻找一种在Numpy中的线性索引和多维索引之间进行相互转换的快速方法。

为了使我的用法具体化,我收集了N个粒子,每个粒子都分配了5个浮点值(尺寸),给出了Nx5数组。然后,我使用numpy.digitize对每个维度进行分箱,并选择适当的分箱边界,以在5维空间中为每个粒子分配一个分箱。

N = 10
ndims = 5
p = numpy.random.normal(size=(N,ndims))
for idim in xrange(ndims):
    bbnds[idim] = numpy.array([-float('inf')]+[-2.,-1.,0.,1.,2.]+[float('inf')])

binassign = ndims*[None]
for idim in xrange(ndims):
    binassign[idim] = numpy.digitize(p[:,idim],bbnds[idim]) - 1

然后,binassign包含与多维索引对应的行。然后,如果我想将多维索引转换为线性索引,我想我想做些类似的事情:

linind = numpy.arange(6**5).reshape(6,6,6,6,6)

这样可以查找每个多维索引,以将其映射到线性索引。然后,您可以使用以下命令返回:

mindx = numpy.unravel_index(x,linind.shape)

我遇到困难的地方是弄清楚如何获取每行包含多维索引的binassign(Nx5数组),并通过使用它对线性索引数组linind进行切片,将其覆盖为一维线性索引。

如果有人采用一种(或几种)线索引技巧在多维索引和线性索引之间来回移动,这种方式可以向量化所有N个粒子的运算,我将不胜感激。


问题答案:

尽管我非常喜欢EOL的答案,但我还是想对每个方向上的仓数不均匀进行概括,并强调C和F排序样式之间的差异。这是一个示例解决方案:

ndims = 5
N = 10

# Define bin boundaries 
binbnds = ndims*[None]
nbins = []
for idim in xrange(ndims):
    binbnds[idim] = numpy.linspace(-10.0,10.0,numpy.random.randint(2,15))
    binbnds[idim][0] = -float('inf')
    binbnds[idim][-1] = float('inf')
    nbins.append(binbnds[idim].shape[0]-1)

nstates = numpy.cumprod(nbins)[-1]

# Define variable values for N particles in ndims dimensions
p = numpy.random.normal(size=(N,ndims))

# Assign to bins along each dimension
binassign = ndims*[None]
for idim in xrange(ndims):
    binassign[idim] = numpy.digitize(p[:,idim],binbnds[idim]) - 1

binassign = numpy.array(binassign)

# multidimensional array with elements mapping from multidim to linear index
# Two different arrays for C vs F ordering
linind_C = numpy.arange(nstates).reshape(nbins,order='C')
linind_F = numpy.arange(nstates).reshape(nbins,order='F')

现在进行转换

# Fast conversion to linear index
b_F = numpy.cumprod([1] + nbins)[:-1]
b_C = numpy.cumprod([1] + nbins[::-1])[:-1][::-1]

box_index_F = numpy.dot(b_F,binassign)
box_index_C = numpy.dot(b_C,binassign)

并检查正确性:

# Check
print 'Checking correct mapping for each particle F order'
for k in xrange(N):
    ii = box_index_F[k]
    jj = linind_F[tuple(binassign[:,k])]
    print 'particle %d %s (%d %d)' % (k,ii == jj,ii,jj)

print 'Checking correct mapping for each particle C order'
for k in xrange(N):
    ii = box_index_C[k]
    jj = linind_C[tuple(binassign[:,k])]
    print 'particle %d %s (%d %d)' % (k,ii == jj,ii,jj)

为了完整起见,如果您想以快速,矢量化的方式从1d索引返回到多维索引:

print 'Convert C-style from linear to multi'
x = box_index_C.reshape(-1,1)
bassign_rev_C = x / b_C % nbins

print 'Convert F-style from linear to multi'
x = box_index_F.reshape(-1,1)
bassign_rev_F = x / b_F % nbins

并再次检查:

print 'Check C-order'
for k in xrange(N):
    ii = tuple(binassign[:,k])
    jj = tuple(bassign_rev_C[k,:])
    print ii==jj,ii,jj

print 'Check F-order'
for k in xrange(N):
    ii = tuple(binassign[:,k])
    jj = tuple(bassign_rev_F[k,:])
    print ii==jj,ii,jj


 类似资料:
  • 问题内容: 我有一个索引元组数组,我想用它从多维numpy数组中选取值, 理解只有在已知的情况下才有效。 有什么提示吗? 问题答案: 您可以将的转置版本转换为元组,然后为矢量化解决方案建立索引-

  • 我有大量相同类型的实体,每个实体都有大量属性,并且我只有以下两种选择来存储它们: 将每个项存储在索引中并执行多索引搜索 将所有enties存储在单个索引中,并且只搜索1个索引。 一般而言,我想要一个时间复杂度之间的比较搜索“N”实体与“M”特征在上述每一种情况!

  • 问题内容: 我在MySQL数据库中有下表: SQL将如下所示: 如您所见,我同时创建了primaryId和和imgDate索引键。我的想法是,该WHERE子句使用primaryId,而ORDER子句使用来查询结果imgDate。 我的问题是,现在使用多索引会更好吗?还是我应该使用多列索引(目前我不太了解)? 这是我从EXPLAIN得到的: 注意:这不是使用多列索引,这是使用上表说明的结果。 问题答

  • 什么是站点索引量   站点中有多少页面可以作为搜索候选结果,就是一个网站的索引量。  站点内容页面需要经过搜索引擎的抓取和层层筛选后,方可在搜索结果中展现给用户。页面通过系统筛选,并被作为搜索候选结果的过程,即为建立索引。  目前site语法的数值是索引量估算值,比较不准。推荐站长们使用我们的新工具,同时我们也正在努力改进site语法。  如何使用百度索引量工具 第一步,注册并登录百度搜索资源平台

  • 本文向大家介绍MySQL索引之主键索引,包括了MySQL索引之主键索引的使用技巧和注意事项,需要的朋友参考一下 在MySQL里,主键索引和辅助索引分别是什么意思,有什么区别? 上次的分享我们介绍了聚集索引和非聚集索引的区别,本次我们继续介绍主键索引和辅助索引的区别。 1、主键索引 主键索引,简称主键,原文是PRIMARY KEY,由一个或多个列组成,用于唯一性标识数据表中的某一条记录。一个表可以没

  • 本文向大家介绍反向索引与正向索引之间的差异,包括了反向索引与正向索引之间的差异的使用技巧和注意事项,需要的朋友参考一下 反向索引和正向索引是用于在一个文档或一组文档中搜索文本的数据结构。 倒排索引 倒排索引将单词存储为索引,将文档名称存储为映射参考。 远期指数 转发索引将文档名称存储为索引,将单词存储为映射参考。 以下是倒排索引和正向索引之间的一些重要区别。 序号 键 倒排索引 远期指数 1 映射