我创建了一个2d Numpy字符串数组,如下所示:
a = np.full((2, 3), '#', dtype=np.unicode)
print(a)
输出是:
array([['#', '#', '#'], ['#', '#', '#']], dtype=`'<U1'`)
我想用'?'来填充它在宽度为1的所有方面。我期望输出为:
array([
['?', '?', '?', '?', '?'],
['?', '#', '#', '#', '?'],
['?', '#', '#', '#', '?'],
['?', '#', '#', '#', '?'],
['?', '?', '?', '?', '?']],
dtype=`'<U1')
我尝试了以下方法:
b = np.pad(a, ((1, 1), (1, 1)), 'constant', constant_values=(('?', '?'), ('?', '?')))
但是这会产生以下错误:
File "<stdin>", line 1, in <module>
File "/usr/lib/python3/dist-packages/numpy/lib/arraypad.py", line 1357, in pad
cast_to_int=False)
File "/usr/lib/python3/dist-packages/numpy/lib/arraypad.py", line 1069, in _normalize_shape
return tuple(tuple(axis) for axis in arr.tolist())
AttributeError: 'tuple' object has no attribute 'tolist'
类似的代码适用于整数。我对字符串做错了什么?
您无法使用字符串文字填充数组。相反,如文档中所述,您可以使用pad_with
函数,如下所示:
In [79]: def pad_with(vector, pad_width, iaxis, kwargs):
...: pad_value = kwargs.get('padder', '?')
...: vector[:pad_width[0]] = pad_value
...: vector[-pad_width[1]:] = pad_value
...: return vector
...:
In [80]:
In [80]: np.pad(a, 1, pad_with)
Out[80]:
array([['?', '?', '?', '?', '?'],
['?', '#', '#', '#', '?'],
['?', '#', '#', '#', '?'],
['?', '#', '#', '#', '?'],
['?', '?', '?', '?', '?']], dtype='<U1')
请注意,在pad_value = kwargs.get('padder', '?')
函数的pad_with
行中,如果np.pad
的调用者没有提供填充参数,则应使用默认的填充值。您将预期的padder
作为关键字参数传递给函数。
In [82]: np.pad(a, 1, pad_with, padder='*')
Out[82]:
array([['*', '*', '*', '*', '*'],
['*', '#', '#', '#', '*'],
['*', '#', '#', '#', '*'],
['*', '#', '#', '#', '*'],
['*', '*', '*', '*', '*']], dtype='<U1')
即使你可以让pad
工作,将a
插入空白的b
会更快。 pad
是针对复杂的填充模式设置的,并且可以迭代地逐行完成工作 - 逐列,逐列。
In [29]: a = np.full((2,3),'#')
In [30]: a
Out[30]:
array([['#', '#', '#'],
['#', '#', '#']], dtype='<U1')
In [31]: b = np.full((4,5),'?')
In [32]: b
Out[32]:
array([['?', '?', '?', '?', '?'],
['?', '?', '?', '?', '?'],
['?', '?', '?', '?', '?'],
['?', '?', '?', '?', '?']], dtype='<U1')
In [33]: b[1:-1,1:-1] = a
In [34]: b
Out[34]:
array([['?', '?', '?', '?', '?'],
['?', '#', '#', '#', '?'],
['?', '#', '#', '#', '?'],
['?', '?', '?', '?', '?']], dtype='<U1')
这是一个聪明的pad_with
解决方案,添加了一个打印,所以我们可以看到它被调用的频率:
In [36]: def pad_with(vector, pad_width, iaxis, kwargs):
...: ...: print(vector)
...: ...: pad_value = kwargs.get('padder', '?')
...: ...: vector[:pad_width[0]] = pad_value
...: ...: vector[-pad_width[1]:] = pad_value
...: ...: return vector
...:
In [37]: np.pad(a,1,pad_with)
['' '' '' '']
['' '#' '#' '']
['' '#' '#' '']
['' '#' '#' '']
['' '' '' '']
['?' '?' '?' '?' '?']
['' '#' '#' '#' '']
['' '#' '#' '#' '']
['?' '?' '?' '?' '?']
Out[37]:
array([['?', '?', '?', '?', '?'],
['?', '#', '#', '#', '?'],
['?', '#', '#', '#', '?'],
['?', '?', '?', '?', '?']], dtype='<U1')