0

我有两个NumPy行数相同的数组,但我想添加特定的列。

我尝试了以下方法:

src_array[:, 3] += column_array_to_add[:, 0]

但是,这甚至不能解释。这样做的正确方法是什么NumPy?我希望能够用整数和字符串来做到这一点。

编辑:一个简短的、独立的测试脚本

import numpy
src = numpy.array([["a", "b"], ["c", "d"], ["e", "f"]])
src2 = numpy.array([["x"], ["y"], ["z"]])

src[:, 1] += src2[:, 0]
print src
exit()

此脚本返回以下错误:

src[:, 1] += src2[:, 0]
TypeError: unsupported operand type(s) for +=: 'numpy.ndarray' and 'numpy.ndarray'
4

2 回答 2

5

这样的事情有用吗?

import numpy as np

x = np.array([[1,2],[3,4]])

y = np.array([[5,6],[7,8]])

结果

>>> x
array([[1, 2],
       [3, 4]])
>>> y
array([[5, 6],
       [7, 8]])
>>> x[:,1] + y[:,1]
array([ 8, 12])
>>> x[:, 1] += y[:, 1] # using +=
>>> x[:, 1]
array([ 8, 12])

更新:

我认为这应该适合你:

src = np.array([["a", "b"], ["c", "d"], ["e", "f"]], dtype='|S8')
src2 = np.array([["x"], ["y"], ["z"]], dtype='|S8')

def add_columns(x, y):
    return [a + b for a,b in zip(x, y)]

def update_array(source_array, col_num, add_col):
    temp_col = add_columns(source_array[:, col_num], add_col)
    source_array[:, col_num] = temp_col  
    return source_array

结果:

>>> update_array(src, 1, src2[:,0])
array([['a', 'bx'],
       ['c', 'dy'],
       ['e', 'fz']], 
      dtype='|S8')
于 2012-12-06T01:43:37.260 回答
0

当您需要调试此类事情时,将其分解为更简单的步骤很有用。您是否弄错了切片,添加了两种不兼容的数组类型,添加了两种类型但试图将结果粘贴到不兼容的类型中(使用+=when+是 OK 但=不是),或者添加不兼容的数据值?其中任何一个都可以提高TypeError,那么我们怎么知道你在做什么呢?

好吧,一次做,看看:

切片:

>>> src[:, 1]
array(['b', 'd', 'f'], dtype='|S1')
>>> src[:, 1] = ['x', 'y', 'z']
>>> src
>>> array([['a', 'x'], ['c', 'y'], ['e', 'z']], dtype='|S1')

没关系。添加呢?

>>> src + src2
TypeError: unsupported operand type(s) for +: 'numpy.ndarray' and 'numpy.ndarray'

因此,我们已经发现了与您的更复杂情况相同的错误,没有切片,也没有+=,这使得调试更加容易。让我们更简单:

>>> s1, s2 = np.array('a'), np.array('b')
>>> s1 + s2
TypeError: unsupported operand type(s) for +: 'numpy.ndarray' and 'numpy.ndarray'

所以即使添加两个 0D 数组也会失败!没有比这更简单的了。

也许是数据类型。如果我们使用整数会发生什么?

>>> n1, n2 = np.array(1), np.array(2)
>>> n1 + n2
3

你可以一直回到你原来的例子,使用整数而不是字符串,它仍然可以正常工作:

>>> m1 = np.array([[1,2], [3,4], [5,6]])
>>> m2 = np.array([[7], [8], [9]])
>>> m1[:, 1] += m2[:, 0]
>>> array([[ 1,  9],
           [ 3, 12],
           [ 5, 15]])

这应该很明显问题出在数据类型上。那么,数据类型是什么?只需打印出数组,看看numpy它是什么:

>>> src = numpy.array([["a", "b"], ["c", "d"], ["e", "f"]])
>>> src
array([['a', 'b'], ['c', 'd'], ['e', 'f']], dtype='|S1')

'|S1'不是您在数据类型的用户指南部分中看到的友好数据类型之一它是一个结构定义,如结构化数组部分中所述。这意味着一个 1 个字符的固定长度字符串。

这使问题变得显而易见:您不能添加两个 1 字符的固定长度字符串,因为结果不是 1 字符的固定长度字符串。

如果您真的想按原样工作,简单的解决方案是将它们保留为 Python 字符串:

>>> src = numpy.array([["a", "b"], ["c", "d"], ["e", "f"]], dtype=object)
>>> src2 = numpy.array([["x"], ["y"], ["z"]], dtype=object)    
>>> src[:, 1] += src2[:, 0]

没有了TypeError

或者,如果您明确给出srcdtype |S2numpy将允许这样做,并且第二个字符将为空白。它不会让你在其中添加另一个|S1,但你可以在 Python 中循环,或者找到一种复杂的方法来numpy为你做这件事。无论哪种方式,您当然不会获得任何通常的时间性能优势numpy,但您仍然可以获得使用固定尺寸固定单元的空间性能优势。

但你可能想退后一步,问问你想离开numpy这里做什么。你在这里的实际更高层次的目标是什么?大部分好处numpy来自使用numpy知道如何使用的严格的 C/Fortran 风格的数据类型——它可以将它们紧密打包,无需额外的解引用(并且无需引用计数)即可访问它们,以多种方式进行操作,从乘法到在没有 Python 等帮助的情况下复制到打印,但它不能进行字符串操作。如果您尝试对字符串操作进行矢量化,则说明您使用了错误的库来执行此操作。如果您只是numpy因为有人说它很快而使用它,那么在很多情况下都是如此,但在这一次却不是。如果您正在使用numpy,因为其他一些代码正在向您传递numpy数据,但您没有numpy方式,没有什么能阻止您将其转换为纯 Python 数据。

于 2012-12-06T18:54:43.900 回答