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

以矢量化方式连接给定范围的开始,结束编号的范围数组-NumPy

邵诚
2023-03-14
问题内容

我有两个感兴趣的矩阵,第一个是“单词袋”矩阵,有两列:文档ID和术语ID。例如:

bow[0:10]

Out[1]:
    array([[ 0, 10],
           [ 0, 12],
           [ 0, 19],
           [ 0, 20],
           [ 1,  9],
           [ 1, 24],
           [ 2, 33],
           [ 2, 34],
           [ 2, 35],
           [ 3, 2]])

另外,我有一个“索引”矩阵,其中矩阵的每一行都包含单词袋矩阵中给定文档ID的第一行和最后一行的索引。例如:第0行是文档ID 0的第一个和最后一个索引。例如:

index[0:4]

Out[2]:
    array([[ 0,  4],
           [ 4,  6],
           [ 6,  9],
           [ 9, 10]])

我想做的是随机抽取文档ID的样本,并获取这些文档ID的所有单词行。单词袋矩阵大约有1.5亿行(〜1.5Gb),因此使用numpy.in1d()太慢了。我们需要迅速将它们退还,以用于下游任务。

我想出的天真的解决方案如下:

def get_rows(ids):
    indices = np.concatenate([np.arange(x1, x2) for x1,x2 in index[ids]])
    return bow[indices]

get_rows([4,10,3,5])

通用样本

提出问题的通用示例将是这样的-

indices = np.array([[ 4, 7],
                    [10,16],
                    [11,18]]

预期的输出将是-

array([ 4,  5,  6, 10, 11, 12, 13, 14, 15, 11, 12, 13, 14, 15, 16, 17])

问题答案:

认为我终于用cumsum向量化解决方案的技巧破解了它-

def create_ranges(a):
    l = a[:,1] - a[:,0]
    clens = l.cumsum()
    ids = np.ones(clens[-1],dtype=int)
    ids[0] = a[0,0]
    ids[clens[:-1]] = a[1:,0] - a[:-1,1]+1
    out = ids.cumsum()
    return out

样品运行-

In [416]: a = np.array([[4,7],[10,16],[11,18]])

In [417]: create_ranges(a)
Out[417]: array([ 4,  5,  6, 10, 11, 12, 13, 14, 15, 11, 12, 13, 14, 15, 16, 17])

In [425]: a = np.array([[-2,4],[-5,2],[11,12]])

In [426]: create_ranges(a)
Out[426]: array([-2, -1,  0,  1,  2,  3, -5, -4, -3, -2, -1,  0,  1, 11])

如果给定开始和停止两个1D数组,则只需要使用它们代替第一列和第二列即可。为了完整起见,这是完整的代码-

def create_ranges(starts, ends):
    l = ends - starts
    clens = l.cumsum()
    ids = np.ones(clens[-1],dtype=int)
    ids[0] = starts[0]
    ids[clens[:-1]] = starts[1:] - ends[:-1]+1
    out = ids.cumsum()
    return out


 类似资料:
  • 初始化一个数组,该数组包含指定范围内的数字,包括 start 和 end ,数字间隔为 step 。 使用 Array.from(Math.ceil((end+1-start)/step)) 创建一个所需长度的数组(元素的数量等于 (end-start)/step 或者 (end+1-start)/step 包括 end ), 用 Array.map() 填充在这个范围内要求的值。 你可以省略 s

  • 使用指定的值初始化和填充数组。 使用 Array(n) 创建所需长度的数组,使用 fill(v) 以填充所需的值。 你可以忽略 val ,使用默认值 0。 const initializeArrayWithValues = (n, val = 0) => Array(n).fill(val); initializeArrayWithValues(5, 2); // [2,2,2,2,2]

  • 是否可以跟踪卡桑德拉的“预订”? 基本上,我的大多数查询将涉及一个和一个,我希望在其中找到与该时间相交的所有保留。 我的模式如下所示: 我输入了一些数据,如下所示: 我正在尝试这样的查询: 我得到一个这样的错误: 我认为这是可以做到的,因为在这个SO问题中似乎是这样的:在cassandra中存储时间范围 但是,架构没有发布,我们也没有使用pycassa,而且我似乎无法弄清楚如何将其映射到CQL。

  • 我正在尝试编写一个Heap排序方法,它只在传入方法的给定范围内执行排序。传入的范围是低和高,这些值对应于堆中的值,而不是堆的索引。例如,输入数组可能是:28 10 49 20 59 61 17,如果low=49,high=61,Heap排序后的结果数组将看起来像这样:28 10 20 49 59 61 17。范围之外的值保持不变。我已经有了一个工作的Heap排序方法,但我的问题是如何修改这个方法以

  • 问题 你想定义一个数组的范围。 解决方案 在 CoffeeScript 中,有两种方式定义数组元素的范围。 myArray = [1..10] # => [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ] myArray = [1...10] # => [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ] 要想反转元素的范围,则可以写成下面这样。 myLargeArray =

  • 问题内容: 我知道变量作用域由块的开始和块的结尾包围。如果在块内声明了相同的变量,则会发生编译错误。但是,请看以下示例。 在这里,可以在方法中重新声明,尽管它已经在类中声明了。但是在块中,无法重新声明。 为什么类范围变量的重新声明不产生错误,而方法范围变量的重新声明却产生错误? 问题答案: 这是因为不是变量,而是实例字段。允许局部变量与字段具有相同的名称。为了区分变量和具有相同名称的字段,我们在实