Поддержка строк Cython

Вы можете использовать dot-notation для доступа и установки полей глубоко внутри объектов, не влияя на другие свойства этих объектов.

Учитывая объект, указанный вами выше:

> db.test.insert({"id": "test_object", "some_key": {"param1": "val1", "param2": "val2", "param3": "val3"}})
WriteResult({ "nInserted" : 1 })

Мы можем обновить только some_key.param2 и some_key.param3:

> db.test.findAndModify({
... query: {"id": "test_object"},
... update: {"$set": {"some_key.param2": "val2_new", "some_key.param3": "val3_new"}},
... new: true
... })
{
    "_id" : ObjectId("56476e04e5f19d86ece5b81d"),
    "id" : "test_object",
    "some_key" : {
        "param1" : "val1",
        "param2" : "val2_new",
        "param3" : "val3_new"
    }
}

Вы можете вникать так глубоко, как вам нравится. Это также полезно для добавления новых свойств к объекту без влияния на существующие.

-2
задан feedMe 18 January 2019 в 11:54
поделиться

1 ответ

Вы можете получить довольно хорошее ускорение для второй части проблемы (которую вы делаете посредством поиска по словарю), используя только Numpy. Я заменил поиск по словарю путем индексации в массив Numpy.

Я генерирую массив Numpy в начале. Одна хитрость заключается в том, чтобы понять, что буквы могут быть преобразованы в базовое число, которое представляет их, используя ord. Для строки ASCII это всегда между 0 и 127:

_base642bin_array = np.zeros((128,),dtype=np.uint8)
for i in range(len(_base64chars)):
    _base642bin_array[ord(_base64chars[i])] = i

Я выполняю преобразование в 1 и 0 в функции n_decompress, используя встроенную функцию numpy.

def n_decompress2(compressed_vector):
    # encode is for Python 3: str -> bytes
    decompressed_b64 = "".join(_decompress_get(compressed_vector)).encode()
    # byte string into the underlying numeric data
    decompressed_b64 = np.fromstring(decompressed_b64,dtype=np.uint8)
    # conversion done by numpy indexing rather than dictionary lookup
    vectorized = _base642bin_array[decompressed_b64]
    # convert to a 2D array of 1s and 0s
    as_binary = np.unpackbits(vectorized[:,np.newaxis],axis=1)
    # remove the two digits you don't care about (always 0) from binary array
    as_binary = as_binary[:,2:]
    # reshape to 1D (and chop off two at the end)
    return as_binary.ravel()[:-2]

Это дает мне 2,4-кратную скорость по сравнению с вашей версией (обратите внимание, что я вообще не изменил _decompress_get, поэтому оба времени включают в себя ваш _decompress_get) только от использования Numpy (без Cython / Numba, и Я подозреваю, что они не слишком помогут). Я думаю, что главное преимущество заключается в том, что индексирование в массив с числами происходит быстрее по сравнению с поиском в словаре.


_decompress_get, вероятно, можно улучшить с помощью Cython, но это значительно сложнее ...

0
ответ дан DavidW 18 January 2019 в 11:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: