如何根据已知ndarray获得形状相同且全为N的新ndarray?
发布于 作者:苏南大叔 来源:程序如此灵动~

本篇文章说的这几个函数,可以复制指定ndarray
的shape
信息。然后在这些指定形状的空位上,填充上相同的目标数据。有点像卡卡西的忍术复制功能。这些特殊的numpy
功能函数就是:.zeros_like()
、.ones_like()
以及.full_like()
。

苏南大叔的“程序如此灵动”技术博客,记录苏南大叔的代码经验总结。本文测试环境:win10
,python@3.11.0
,numpy@1.24.2
。
前文回顾
在以前的文章中,苏南大叔曾经描述过:如何快速获得全为N的ndarray,并且也是有参数可以指定shape
的。和本文的使用场景非常类似,只不过是本文的场景中,是去拓扑替换一个已有的ndarray
。
本文对比专用范例:
输出:
参考文章:
基础测试代码
函数名称是:.zeros_like()
、.ones_like()
以及.full_like()
。那么可以望文生义一下,然后再看看下面代码的运行结果。
输出:
稍稍变换的测试代码
如果你以为轻松的通过望文生义了解了这几个_like
系列函数,那么,请看下面的代码:
输出:

很显然,每个结果似乎都出乎意料,都不符合预期。
zeros_like
,变成了空字符串。ones_like
,变成了字符串1。full_like
,不但变成了字符串,而且每个元素的长度也被限制为1。
所以,结论是:表面上这些_like()
函数,复制的是目标变量的形状。实际上连目标变量的元素类型和长度也是完全复制的。这有些像苏南大叔以前写过的一篇文章:
表格总结
函数 | 说明 |
---|---|
np.zeros_like(target) | 原始元素是字符串的时候,返回的也是字符串,并且是空字符 |
np.ones_like(target) | 数字1或者字符串1 |
np.full_like(target,item) | item的类型及长度受原始元素的限制 |
这里可以想想看,在any()
或者all()
判断里面,为啥要把0
、False
、None
还有空字符串,划为等号。
思考题目一
猜猜看,下面的代码输出是什么?
输出:
是不是,依然非常出乎意料?
思考题目二
下面的代码,运行结果更加出乎意料:
输出:
- 填充
False
,这次变成了整数0,而是不是字符串F
。 - 填充
None
,直接报错,而是不是字符串N
。 - 填充``,直接报错。
可能更好的方案
对比np.xxx_like()
的不可控(原变量的dtype
影响新变量),苏南大叔还是比较喜欢结果可控的代码:
输出结果,完全都在意料之中!可控!靠谱!
结束语
综合上述观点,np.xxx_like()
系列的函数,不光复制形状,还复制其它的特殊信息。这个过程是很不可控的。所以,如果可能,还是尽量使用本来最开始的那个np.zeros(shape)
、np.ones(shape)
、np.full(shape,item)
来完成这个需求吧。
更多python
精彩文章,请参考苏南大叔的博客:


