Numpy高效索引与不同大小的数组

时间:2016-09-15 10:31:01

标签: python arrays numpy

看一下这段代码:

import numpy as np

a = np.random.random(10)

indicies = [
    np.array([1, 4, 3]),
    np.array([2, 5, 8, 7, 3]),
    np.array([1, 2]),
    np.array([3, 2, 1])
]

result = np.zeros(2)
result[0] = a[indicies[0]].sum()
result[1] = a[indicies[2]].sum()

有没有办法让result更有效率?在我的情况下,a是一个非常大的数组。

换句话说,我想从a中选择具有多个不同大小索引数组的元素,然后在一个操作中对它们求和,得到一个数组。

2 个答案:

答案 0 :(得分:0)

使用您的indiciesIn [280]: [a[i].sum() for i in indicies] Out[280]: [1.3986792680307709, 2.6354365193743732, 0.83324677494990895, 1.8195179021311731] 列表:

np.array()

当然可以包含在indicies中。

对于In [281]: [a[indicies[i]].sum() for i in [0,2]] Out[281]: [1.3986792680307709, 0.83324677494990895] 项的子集,请使用:

indicies

评论建议In [289]: A=np.zeros((4,10),int) In [290]: for i in range(4): A[i,indicies[i]]=1 In [291]: A Out[291]: array([[0, 1, 0, 1, 1, 0, 0, 0, 0, 0], [0, 0, 1, 1, 0, 1, 0, 1, 1, 0], [0, 1, 1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 1, 1, 0, 0, 0, 0, 0, 0]]) 来自邻接矩阵,可能是稀疏的。

我可以用:

重新创建这样一个数组
np.dot

并使用矩阵乘积(In [292]: A.dot(a) Out[292]: array([ 1.39867927, 2.63543652, 0.83324677, 1.8195179 ]) )进行选择并求和:

A[[0,2],:].dot(a)

In [294]: Al=sparse.lil_matrix(A) In [295]: Al.rows Out[295]: array([[1, 3, 4], [2, 3, 5, 7, 8], [1, 2], [1, 2, 3]], dtype=object) 将使用行的子集。

稀疏矩阵版本具有行索引列表:

In [296]: Al*a
Out[296]: array([ 1.39867927,  2.63543652,  0.83324677,  1.8195179 ])

带有相同数字的矩阵产品:

//this is the byte stream that I upload.
public static byte[] getStreamByteFromImage(final File imageFile) {

    Bitmap photoBitmap = BitmapFactory.decodeFile(imageFile.getPath());
    ByteArrayOutputStream stream = new ByteArrayOutputStream();

    int imageRotation = getImageRotation(imageFile);

    if (imageRotation != 0)
        photoBitmap = getBitmapRotatedByDegree(photoBitmap, imageRotation);

    photoBitmap.compress(Bitmap.CompressFormat.JPEG, 70, stream);

    return stream.toByteArray();
}



private static int getImageRotation(final File imageFile) {

    ExifInterface exif = null;
    int exifRotation = 0;

    try {
        exif = new ExifInterface(imageFile.getPath());
        exifRotation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
    } catch (IOException e) {
        e.printStackTrace();
    }

    if (exif == null)
        return 0;
    else
        return exifToDegrees(exifRotation);
}

private static int exifToDegrees(int rotation) {
    if (rotation == ExifInterface.ORIENTATION_ROTATE_90)
        return 90;
    else if (rotation == ExifInterface.ORIENTATION_ROTATE_180)
        return 180;
    else if (rotation == ExifInterface.ORIENTATION_ROTATE_270)
        return 270;

    return 0;
}

private static Bitmap getBitmapRotatedByDegree(Bitmap bitmap, int rotationDegree) {
    Matrix matrix = new Matrix();
    matrix.preRotate(rotationDegree);

    return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}

答案 1 :(得分:-1)

如果您的数组 a 非常大,那么如果索引数组在循环时包含许多索引数组,则可能会出现内存问题

要避免此问题,请使用迭代器而不是列表:

indices = iter(indices)

然后遍历你的迭代器。