2017-02-19 4 views
0

Я получаю два разных результата для некоторых входов, но не для других. Позвольте мне объяснить, используя конкретный пример. У меня есть следующие функции:Странные результаты при использовании массивов numpy

In [86]: def f(x, p): 
    ...:  n = len(p) 
    ...:  tot = 0 
    ...:  for i in range(n): 
    ...:   tot += p[i] * x**(n-i-1) 
    ...:  return tot 

p представляет собой массив с очень малыми значениями:

In [87]: p 
Out[87]: 
array([ -3.93107522e-45, 9.17048746e-40, -8.11593366e-35, 
     3.05584286e-30, -1.06065846e-26, -3.03946945e-21, 
     1.05944707e-16, -1.56986924e-12, 1.07293061e-08, 
     -3.22670121e-05, 1.12072912e-01]) 

Теперь рассмотрим выходы:

In [90]: [f(i, p) for i in range(11, 20)] 
Out[90]: 
[0.11171927108787173, 
0.1116872502272328, 
0.1116552507123586, 
0.11162327253386167, 
0.11159131568235707, 
0.11155938014846242, 
0.1115274659227979, 
0.11149557299598616, 
0.11146370135865244] 

In [88]: [f(i, p) for i in np.array(range(11, 20))] 
Out[88]: 
[0.11171927108787173, 
0.1116872502272328, 
0.1116552507123586, 
0.11162327253386167, 
0.11159131568235707, 
0.11155938014846242, 
0.1115274659227979, 
0.11149557299598616, 
0.11146370135865244] 

Как вы можете видеть, эти результаты являются точно как и должно быть. Единственное различие заключается в том, что в одном случае я использую range(a, b), а в другом случае я преобразовываю этот диапазон в массив numpy.

Но теперь, давайте изменим значения в диапазоне:

In [91]: [f(i, p) for i in range(50001, 50010)] 
Out[91]: 
[-0.011943965521167818, 
-0.011967640114171604, 
-0.011991315947644229, 
-0.012014993019120554, 
-0.012038671327427961, 
-0.012062350870605351, 
-0.012086031644648818, 
-0.012109713648648865, 
-0.012133396879791744] 

In [92]: [f(i, p) for i in np.array(range(50001, 50010))] 
Out[92]: 
[491.26519430165808, 
491.32457916465478, 
491.38395932037008, 
491.38726606180143, 
491.44663641006275, 
491.50600185375316, 
491.56536239249812, 
491.56864971072332, 
491.6280006336612] 

И они даже не близко! Я пропустил что-то смехотворно простое?

+1

Это похоже на проблему интерьеров. на более новых версиях python ints имеют неограниченный диапазон, вы можете проверить это, набрав что-то нелепое, как 10 ** 100-1. numpy ints - это C longs, поэтому они не обеспечивают эту роскошь. –

ответ

2

Вам не хватает того, что обычные целые числа на Python являются произвольными значениями, а целые числа NumPy имеют фиксированный размер.

Это:

x**(n-i-1) 

перетекает с входами NumPy.

+0

Вижу. Что такое средство, потому что у меня есть массив numpy в фактическом коде. Фактически, это серия Панд. – Peaceful

+0

@Peaceful: используйте числа с плавающей запятой. – user2357112

1

Значения в f(x, p) для x в случае ошибки, относятся к типу numpy.int32. Они могут переполняться. Исправление в этом случае относительно прямое, преобразуйте значения в int:

tot += p[i] * np.asarray(x).astype(int) ** (n - i - 1) 
+0

Это может не работать, когда 'x' передается как массив numpy. Правильно? – Peaceful

+0

Хм. Тем не менее, это порождает ошибку в моем случае: 'TypeError: только массивы length-1 могут быть преобразованы в сканеры Python' – Peaceful

+0

Спасибо, обновлено ... –

Смежные вопросы