代码之家  ›  专栏  ›  技术社区  ›  Thomas Ahle

在numpy/pyptorch中进行多次切片

  •  1
  • Thomas Ahle  · 技术社区  · 4 年前

    我有一个很大的一维数组 X.shape = (10000,) ,和一个索引向量 y = [0, 7, 9995]

    我想要一个带行的矩阵

    [
     X[0 : 100],
     X[7 : 107],
     concat(X[9995:], X[:95]),
    ]
    

    也就是说,长度为100的切片,从每个索引开始,并环绕。

    我可以用python循环来实现这一点,但我想知道在pytorch或numpy中是否有更聪明的批量方式来实现这,因为我的数组可能相当大。

    1 回复  |  直到 4 年前
        1
  •  1
  •   user17242583 user17242583    4 年前

    其实很简单。

    1. 对于每个元素 E 在里面 y ,创建范围 E E + 100
    2. 水平连接所有范围
    3. 用的长度对所得数组进行模运算 X
    indexes = np.hstack([np.arange(v, v + 100) for v in y]) % X.shape[0]
    

    输出:

    >>> indexes
    array([   0,    1,    2,    3,    4,    5,    6,    7,    8,    9,   10,
             11,   12,   13,   14,   15,   16,   17,   18,   19,   20,   21,
             22,   23,   24,   25,   26,   27,   28,   29,   30,   31,   32,
             33,   34,   35,   36,   37,   38,   39,   40,   41,   42,   43,
             44,   45,   46,   47,   48,   49,   50,   51,   52,   53,   54,
             55,   56,   57,   58,   59,   60,   61,   62,   63,   64,   65,
             66,   67,   68,   69,   70,   71,   72,   73,   74,   75,   76,
             77,   78,   79,   80,   81,   82,   83,   84,   85,   86,   87,
             88,   89,   90,   91,   92,   93,   94,   95,   96,   97,   98,
             99,    7,    8,    9,   10,   11,   12,   13,   14,   15,   16,
             17,   18,   19,   20,   21,   22,   23,   24,   25,   26,   27,
             28,   29,   30,   31,   32,   33,   34,   35,   36,   37,   38,
             39,   40,   41,   42,   43,   44,   45,   46,   47,   48,   49,
             50,   51,   52,   53,   54,   55,   56,   57,   58,   59,   60,
             61,   62,   63,   64,   65,   66,   67,   68,   69,   70,   71,
             72,   73,   74,   75,   76,   77,   78,   79,   80,   81,   82,
             83,   84,   85,   86,   87,   88,   89,   90,   91,   92,   93,
             94,   95,   96,   97,   98,   99,  100,  101,  102,  103,  104,
            105,  106, 9995, 9996, 9997, 9998, 9999,    0,    1,    2,    3,
              4,    5,    6,    7,    8,    9,   10,   11,   12,   13,   14,
             15,   16,   17,   18,   19,   20,   21,   22,   23,   24,   25,
             26,   27,   28,   29,   30,   31,   32,   33,   34,   35,   36,
             37,   38,   39,   40,   41,   42,   43,   44,   45,   46,   47,
             48,   49,   50,   51,   52,   53,   54,   55,   56,   57,   58,
             59,   60,   61,   62,   63,   64,   65,   66,   67,   68,   69,
             70,   71,   72,   73,   74,   75,   76,   77,   78,   79,   80,
             81,   82,   83,   84,   85,   86,   87,   88,   89,   90,   91,
             92,   93,   94])
    

    现在只使用索引 十、 其中:

    X[indexes]
    
        2
  •  0
  •   Thomas Ahle    3 年前

    这是用户17242583的答案的一个版本,不使用python循环:

    N, BS, S = 10000, 1000, 100
    X = np.random.randn(N)
    h = np.random.randint(N, size=(BS,))
    
    indexes = (h[..., None] + np.arange(S)) % N
    result = X[indexes]
    

    在pytorch中,我还发现了另一种解决方案,使用 unfold :

    wrapped = torch.cat((X, X[:S-1]))
    strides = wrapped.unfold(dimension=0, size=S, step=1)
    result = strides[h]
    

    但我还没有做实验来看看哪一个更有效。

    推荐文章