我有两个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'
答案 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} |S2
,numpy
将允许,第二个字符将为空。它不会让你添加另一个|S1
,但你可以循环使用Python,或者找到一种复杂的方法来修复numpy
为你做这件事。无论哪种方式,当然,你没有获得numpy
的任何通常的时间性能优势,但是你仍然可以获得使用打包的固定大小单元的空间性能优势。
但是你可能想退后一步,问一下你在numpy
想要从这里得到什么。你的实际更高级目标是什么? numpy
的大多数好处来自于使用numpy
知道如何使用的严格C / Fortran风格的数据类型 - 它可以将它们紧密打包,访问它们而无需额外的解引用(并且无需引用计数) ),在没有Python等任何帮助的情况下,从乘法到复制到打印等各种方式进行操作。但它不能进行字符串操作。如果您正在尝试对字符串操作进行矢量化,那么您使用了错误的库来执行此操作。如果你只是使用numpy
,因为有人说它很快,嗯,在许多情况下都是如此,但不是在这个中。如果您使用的是numpy
,因为其他一些代码正在处理numpy
个数据,但您不希望以numpy
的方式处理它,那么就没有什么可以阻止您将其转换为纯Python数据。