【问题标题】:Numpy string array pad with string带字符串的 Numpy 字符串数组填充
【发布时间】:2018-03-01 12:34:58
【问题描述】:

我已经创建了一个二维 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'

类似的代码适用于整数。我对字符串做错了什么?

【问题讨论】:

  • 这只是一个numpy 错误——它的实现细节假设了关于数组的过于具体的条件,并且当它无法继续时它会转储一个无用的消息。正如@Kasramvd 所示,您可以通过创建自己的填充函数来规避它。
  • 我在 1.14 中遇到了另一个错误。请注意,某些模式涉及最大值和插值。 “恒定”模式可能只是其中之一的特例。对于像这样的简单填充来说,这太过分了。

标签: python string python-3.x numpy


【解决方案1】:

你不能用字符串文字填充你的数组。相反,正如提到的in documentation,您可以使用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_with 函数中的pad_value = kwargs.get('padder', '?') 行中,您应该使用默认填充值,以防np.pad 的调用者中没有提供填充参数。您将预期的padder 作为关键字参数传递给函数。

In [82]: np.pad(a, 1, pad_with, padder='*')
Out[82]: 
array([['*', '*', '*', '*', '*'],
       ['*', '#', '#', '#', '*'],
       ['*', '#', '#', '#', '*'],
       ['*', '#', '#', '#', '*'],
       ['*', '*', '*', '*', '*']], dtype='<U1')

【讨论】:

    【解决方案2】:

    即使您可以让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')
    

    【讨论】:

      猜你喜欢
      • 2019-04-11
      • 1970-01-01
      • 2013-06-06
      • 1970-01-01
      • 1970-01-01
      • 2012-06-14
      • 2011-09-07
      • 2017-02-02
      • 1970-01-01
      相关资源
      最近更新 更多