我刚刚加入了两个不等长的数组和命令:
allorders = map(None,todayorders, lastyearorders)
其中“none”给出今天的订单没有值(因为今天的数组不长)。
但是,当我尝试将allorders数组传递到matplotlib条形图时:
p10= plt.bar(ind, allorders[9], width, color='#0000DD', bottom=allorders[8])
..我收到以下错误:
TypeError: unsupported operand type(s) for +=: 'int' and 'NoneType'
那么,matplotlib有没有办法接受无数据类型?如果没有,我如何在我的allorders数组中用零替换'Nones'?
如果可以,因为我是一名Python新手(来自R社区),请提供从头到尾的详细代码,我可以使用/测试。
答案 0 :(得分:6)
使用列表理解:
allorders = [i if i[0] is not None else (0, i[1]) for i in allorders]
答案 1 :(得分:4)
因为听起来你希望这一切都在numpy
中,所以对你的问题的直接回答实际上只是一个旁边,并且正确的答案不会存在"当然......"段落。
如果您考虑一下,那么您使用map
None
第一个参数作为zip_longest
,因为Python没有zip_longest
}。但确实在itertools
中有一个 - 并且它允许您指定自定义fillvalue
。因此,您可以使用izip_longest
一步一步完成此操作:
>>> import itertools
>>> todayorders = [1, 2]
>>> lastyearorders = [1, 2, 3]
>>> allorders = itertools.izip_longest(todayorders, lastyearorders, fillvalue=0)
>>> list(allorders)
[(1, 1), (2, 2), (0, 3)]
这只会填充0
None
,显示为较短列表的额外值;如果你想用None
取代每个 0
,你必须按照Martijn Pieters的方式来做。但我认为这就是你想要的。
另请注意,最后list(allorders)
:izip_longest
与itertools
中的大多数内容一样,返回迭代器,而不是list
。或者,就你可能更熟悉而言,它会返回一个懒惰的"顺序而不是严格的#34;一。如果你只是要迭代结果,那实际上更好,但是如果你需要使用一些需要list
的函数(比如以人类可读的形式打印出来) - 或访问allorders[9]
,如您的示例中所示,您需要先显式转换它。
如果您确实需要numpy.array
而不是list
,则可以直接到达那里,而无需先通过list
。 (如果你所做的只是matplotlib
它,你可能做想要一个array
。)最明显的方法是使用{{ 1}}而不是np.fromiter(allorders)
。您可能希望传递明确的list(allorders)
(或任何适当的)。而且,如果您知道尺寸(您执行的操作dtype=int
),在某些情况下,传递明确的max(len(todayorders), len(lastyearorders))
也会更快或更简单。
当然,如果任何count
内容听起来很有吸引力,那么您可能应该首先留在numpy
内,而不是使用numpy
或map
:
izip_longest
不幸的是,这会改变>>> todayorders.resize(lastyearorders.shape)
>>> allorders = np.vstack(todayorders, lastyearorders).transpose()
,据我所知,等效的不可变函数todayorders
并没有为你提供任何方式来进行零扩展"而是重复这些价值观。希望我错了,有人会建议简单的方法,但除此之外,你必须明确地做:
numpy.resize
当然,如果你做了很多,我会编写一个>>> extrazeros = np.zeros(len(lastyearorders) - len(todayorders), dtype=int)
>>> allorders = np.vstack(np.concatenate((todayorders, extrazeros)), lastyearorders)
>>> allorders = allorders.transpose()
array([[ 1, 1],
[ 2, 2],
[ 0, 3]])
函数,它接受一对数组并扩展一个以匹配另一个(或者,如果你不仅仅是处理1D,在每个轴上扩展较短的一个以制作另一个。)
无论如何,除了比使用zeroextend
,map
等更快且使用更少的临时内存之外,这也意味着你最终得到一个右{{1 (izip_longest
而不是dtype
) - 这意味着你的结果也使用较少的长期记忆,从那时起你所做的一切也会更快,并且使用更少的临时记忆。
为了完整性: 可以int
处理object
值,但我不认为它是你想要的。例如,您可以将pyplot
方法将None
方法转换为Transform
的{{1}}对象传递给它。但这与Martijn Pieters的答案实际上是一样的,但更加冗长,除非你需要绘制大量这样的阵列,否则根本就没有优势。
答案 2 :(得分:2)
numpy:
import numpy as np
allorders = np.array(allorders)
由于Nones,这会创建一个对象阵列。我们可以用零替换它们:
allorders[allorders == None] = 0
然后将数组转换为正确的类型:
allorders.astype(int)