Преобразование массива NumPy в чистое целое число Python, чтобы избежать целочисленного переполнения - PullRequest
0 голосов
/ 16 октября 2018

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

Постановка задачи:

Я нахожусь в ситуации, мне нужна функция произвольной точности чистых чисел Python.В какой-то момент в моем коде у меня есть массив с логическим значением.Что-то вроде:

arr

массив ([True, False, False, False, True, True, True, False, True, True, False, False, True, True, True, False,True, False, False, True, False, True, True, True, True, True, False, True, False, True, True, False, True, True, False, True, False, False, True, False, True,True, False, True, False, True, True, False, True, True, True, False, False, False, True, False, False, True, True, True, True, False, True, False])

, который я конвертирую в numpy.int64, используя arr.astype(int), чтобы сделать его арифметическим.

Но я использовал этот код, чтобы преобразовать его в целое число, которое он переполнил (и создал отрицательные числа, которые я не хочу).

Код использует эту функцию (которая является чистым python и неу меня возникла проблема с целочисленным переполнением):

def bool2int(x):
    y = 0
    for i,j in enumerate(x):
        y += j<<i
    return y

Если я запускаю код непосредственно на np.array (преобразуется в int или нет, это не имеет значения):

bool2int(arr)

-2393826705255337647

bool2int(h.astype(int))

-2393826705255337647

понадобится положительное целое число.Итак, я использовал понимание списка:

bool2int([int(x) for x in arr])

16052917368454213969

Очевидно, число, представленное arr, превышает емкость целых чисел с фиксированной точностью (то есть 2 63 -1), чтобы иметь возможность использовать ti напрямую.

Есть ли какой-либо другой прямой путь для достижения помимо понимания списка?

Редактировать:

Длятеория целочисленного переполнения в Python Я подал в суд на этот источник .

Ответы [ 2 ]

0 голосов
/ 16 октября 2018

Один из способов получения нативных элементов типа Python - .tolist().Обратите внимание, что мы можем сделать это прямо в логическом массиве.Ваш код отлично работает с родными Python bools.

>>> x = np.random.randint(0, 2, (100,)).astype(bool)
>>> x
array([ True,  True, False,  True, False,  True, False, False,  True,
       False, False,  True,  True, False, False, False,  True, False,
       False,  True, False,  True, False, False,  True,  True,  True,
        True,  True,  True,  True, False, False, False, False, False,
        True,  True,  True,  True, False, False,  True, False, False,
       False, False,  True, False,  True,  True, False, False,  True,
       False,  True,  True,  True, False,  True,  True,  True, False,
        True,  True,  True,  True, False,  True,  True,  True, False,
        True, False,  True, False,  True, False,  True,  True,  True,
       False, False,  True,  True,  True,  True,  True, False, False,
        True, False, False, False,  True,  True,  True, False, False,  True], dtype=bool)
>>> bool2int(x)
-4925102932063228254
>>> bool2int(x.tolist())
774014555155191751582008547627L

В качестве дополнительного бонуса он на самом деле быстрее.

>>> timeit(lambda:bool2int(x), number=1000)
0.24346303939819336
>>> timeit(lambda:bool2int(x.tolist()), number=1000)
0.010725975036621094
0 голосов
/ 16 октября 2018

Использование astype(int) работает нормально;следующий код:

import numpy as np

test = np.array([True, False, False, False, True, True, True, False, True, True, False, False, True, True, True, False, True, False, False, True, False, True, True, True, True, True, False, True, False, True, True, False, True, True, False, True, False, False, True, False, True, True, False, True, False, True, True, False, True, True, True, False, False, False, True, False, False, True, True, True, True, False, True, False])
test_int = test.astype(int)

print(test_int)
print(test_int.sum())

Возвраты:

[1 0 0 0 1 1 1 0 1 1 0 0 1 1 1 0 1 0 0 1 0 1 1 1 1 1 0 1 0 1 1 0
1 1 0 1 0 0 1 0 1 1 0 1 0 1 1 0 1 1 1 0 0 0 1 0 0 1 1 1 1 0 1 0]

37

Исключение переполнения, которое вы получаете, кажется маловероятным, поэтому я бы снова посмотрел на это, потому что, возможно, у вас произошла ошибка в другом месте.

Редактировать

Если вы хотите получить тип Python вместо простого объекта, просто выполните:

test.astype(int).tolist()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...