在python 3中将map对象转换为numpy数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28524378/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 03:22:46  来源:igfitidea点击:

Convert map object to numpy array in python 3

pythonpython-3.xnumpy

提问by btel

In Python 2 I could do the following:

在 Python 2 中,我可以执行以下操作:

import numpy as np    
f = lambda x: x**2
seq = map(f, xrange(5))
seq = np.array(seq)
print seq
# prints: [ 0  1  4  9 16]

In Python 3 it does not work anymore:

在 Python 3 中它不再起作用:

import numpy as np    
f = lambda x: x**2
seq = map(f, range(5))
seq = np.array(seq)
print(seq)
# prints: <map object at 0x10341e310>

How do I get the old behaviour (converting the mapresults to numpyarray)?

如何获得旧行为(将map结果转换为numpy数组)?

Edit: As @jonrsharpe pointed out in his answer this could be fixed if I converted seqto a list first:

编辑:正如@jonrsharpe 在他的回答中指出的那样,如果我先转换seq为列表,这可以解决:

seq = np.array(list(seq))

but I would prefer to avoid the extra call to list.

但我更愿意避免额外调用list.

回答by jonrsharpe

Although you refer to it as seq, the mapobject in Python 3 is nota sequence(it's an iterator, see what's new in Python 3). numpy.arrayneeds a sequence so the lencan be determined and the appropriate amount of memory reserved; it won't consume an iterator. For example, the rangeobject, which doessupport most sequence operations, canbe passed directly;

虽然你把它称作seq时,map在Python 3的对象是不是一个序列(这是一个迭代器,看看有什么在Python 3的新功能)。numpy.array需要一个序列,以便len可以确定并保留适当的内存量;它不会消耗迭代器。例如,range对象,它支持大多数序列的操作,可以被直接传递;

seq = np.array(range(5))
print(seq)
# prints: [0 1 2 3 4]

To restore the previous behaviour, as you're aware, you can explicitly convert the mapobject back to a sequence (e.g. list or tuple):

如您所知,要恢复以前的行为,您可以将map对象显式转换回序列(例如列表或元组):

seq = np.array(list(seq))  # should probably change the name!

However, as the documentationputs it:

但是,正如文档所说:

a quick fix is to wrap map()in list(), e.g. list(map(...)), but a better fix is often to use a list comprehension (especially when the original code uses lambda)

速战速决是包装map()list(),如list(map(...)),但更好的解决办法是经常使用列表理解(尤其是当原来的代码使用lambda

So another option would be:

所以另一种选择是:

seq = [f(x) for x in range(5)]

or just:

要不就:

seq = [x**2 for x in range(5)]

Alternatively, actually use numpyfrom the start:

或者,numpy从一开始就实际使用:

import numpy as np    
arr = np.arange(5)
arr **= 2
print(arr)
# prints [ 0  1  4  9 16] in 2.x and 3.x

回答by Oliver W.

One more alternative, other than the valid solutions @jonrsharpe already pointed out is to use np.fromiter:

除了@jonrsharpe 已经指出的有效解决方案之外,另一种选择是使用np.fromiter

>>> import numpy as np    
>>> f = lambda x: x**2
>>> seq = map(f, range(5))
>>> np.fromiter(seq, dtype=np.int)
array([ 0,  1,  4,  9, 16])