如何添加两列numpy数组?

时间:2012-12-06 01:37:55

标签: python numpy

我有两个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'

2 个答案:

答案 0 :(得分: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')

答案 1 :(得分:0)

当你需要调试这种东西时,将它分解为更简单的步骤是有用的。您是否错误地添加了切片,添加了两种不兼容的数组类型,添加了两种类型但尝试将结果粘贴到不兼容的类型中(当+=正常但+不正常时使用=) ,或添加不兼容的数据值?其中任何一个都可以提出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'不是您在Data types的“用户指南”部分中看到的友好数据类型之一,它是一种结构定义,如Structured arrays部分所述。这意味着一个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

或者,如果您明确地给src {d} |S2numpy将允许,第二个字符将为空。它不会让你添加另一个|S1,但你可以循环使用Python,或者找到一种复杂的方法来修复numpy为你做这件事。无论哪种方式,当然,你没有获得numpy的任何通常的时间性能优势,但是你仍然可以获得使用打包的固定大小单元的空间性能优势。

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