简体   繁体   English

numpy数组列出转换问题

[英]numpy array to list conversion issue

For some reason, evalRow(list(array([0, 1, 0, 0, 0]))) and evalRow([0, 1, 0, 0, 0]) give different results.出于某种原因, evalRow(list(array([0, 1, 0, 0, 0])))evalRow([0, 1, 0, 0, 0])给出了不同的结果。 However if I use magicConvert (here to debug this) instead of list to go from numpy array to list it works as expected:但是,如果我使用magicConvert (在这里调试它)而不是list从 numpy 数组转到 list 它会按预期工作:

def magicConvert(a):
  ss = str(list(a))[1:-1]
  return map(int, ss.split(","))

# You don't actually need to read these functions, just here to reproduce the error:
from itertools import *
def evalRow(r):
  grouped = map(
    lambda (v, l): (v, len(tuple(l))),
    groupby(chain([2], r, [2])))
  result = 0
  for player in (1, -1):
    for (pre, mid, post) in allTuples(grouped, 3):
      if mid[0] == player:
        result += player * streakScore(mid[1], (pre[0] == 0) + (post[0] == 0))
  return result

def streakScore(size, blanks):
  return 0 if blanks == 0 else (
    100 ** (size - 1) * (1 if blanks == 1 else 10))

def allTuples(l, size):
  return map(lambda i: l[i : i + size], xrange(len(l) - size + 1))

The difference in the behaviour is due to the fact that doing list(some_array) returns a list of numpy.int64 , while, doing the conversion via the string representation (or equivalently using the tolist() method) returns a list of python's int s:行为的差异是由于执行list(some_array)返回一个numpy.int64列表,而通过字符串表示(或等效地使用tolist()方法)进行转换返回一个 python 的int列表:

In [21]: import numpy as np

In [22]: ar = np.array([1,2,3])

In [23]: list(ar)
Out[23]: [1, 2, 3]

In [24]: type(list(ar)[0])
Out[24]: numpy.int64

In [25]: type(ar.tolist()[0])
Out[25]: builtins.int

I believe the culprit is the 100 ** (size - 1) part of your code:我相信罪魁祸首是代码的100 ** (size - 1)部分:

In [26]: 100 ** (np.int64(50) - 1)
Out[26]: 0

In [27]: 100 ** (50 - 1)
Out[27]: 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

In [28]: type(100 ** (np.int64(50) - 1))
Out[28]: numpy.int64

What you see is the int64 overflowing, hence the result of the exponentiation are essentially "random", while python's int s have unlimited range and give the correct result.您看到的是int64溢出,因此求幂的结果本质上是“随机的”,而 python 的int具有无限范围并给出正确的结果。

To summary:总结:

  • If you want to convert between numpy and python data types use the proper methods, in this case array.tolist()如果要在numpy和 python 数据类型之间进行转换,请使用正确的方法,在这种情况下为array.tolist()
  • Remember that numpy s data types have limited range, hence you should check for overflows and expect strange results in other situations.请记住, numpy的数据类型范围有限,因此应该检查溢出并在其他情况下期待奇怪的结果。 If you do not use the proper methods for conversion you might end up using numpy data types when you didn't expect (as in this case).如果您没有使用正确的转换方法,您可能最终会在意想不到的情况下使用numpy数据类型(如本例)。
  • Never assume it's a bug in python/ numpy /a very widely used library.永远不要认为这是 python/ numpy /一个非常广泛使用的库中的错误。 The chances to find a bug in such trivial cases in such well-tested and widely used softwares is really small .在这些经过充分测试和广泛使用的软件中,在这种微不足道的情况下发现错误的机会非常小 If the program gives unexpected results, 99.999% of the times it's because you are doing something wrong.如果程序给出了意想不到的结果,99.999% 是因为做错了什么。 So, before blaming on others try to check step by step what your program is doing.因此,在责备他人之前,请尝试逐步检查您的程序在做什么。

I tested it and it gave me differnet results.我测试了它,它给了我不同的结果。 Don't ask me why, maybe a bug?不要问我为什么,也许是一个错误?

Anyway always use the tolist() function to convert a numpy array to a list.无论如何,始终使用tolist()函数将 numpy 数组转换为列表。

evalRow(array([0, 1, 0, 0, 0]).tolist()) == evalRow([0, 1, 0, 0, 0])
#output: True

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM