使用 numpy 堆叠一维和二维数组的组合
Use numpy to stack combinations of a 1D and 2D array
我有 2 个 numpy 数组,一个是二维的,另一个是一维的,例如:
import numpy as np
a = np.array(
[
[1, 2],
[3, 4],
[5, 6]
]
)
b = np.array(
[7, 8, 9, 10]
)
我想获取 a
和 b
中元素的所有可能组合,将 a
视为一维数组,以便它保留 [=12= 中的行] 完好无损,但也将 a
中的行与 b
中的项目连接起来。它看起来像这样:
>>> combine1d(a, b)
[ [1 2 7] [1 2 8] [1 2 9] [1 2 10]
[3 4 7] [3 4 8] [3 4 9] [3 4 10]
[5 6 7] [5 6 8] [5 6 9] [5 6 10] ]
我知道对此有缓慢的解决方案(如 for
循环),但我需要一个快速的解决方案,因为我正在处理具有数百万整数的数据集。
有什么想法吗?
这是非常“透明胶带”的解决方案:
import numpy as np
a = np.array(
[
[1, 2],
[3, 4],
[5, 6]
]
)
b = np.array(
[7, 8, 9, 10]
)
z = []
for x in b:
for y in a:
z.append(np.append(y, x))
np.array(z).reshape(3, 4, 3)
您需要使用np.c_
附加以连接两个数据框。我还使用 np.full
生成第二个数组的一列 (b
)。结果如下:
result = [np.c_[a, np.full((a.shape[0],1), x)] for x in b]
result
输出
[array([[1, 2, 7],
[3, 4, 7],
[5, 6, 7]]),
array([[1, 2, 8],
[3, 4, 8],
[5, 6, 8]]),
array([[1, 2, 9],
[3, 4, 9],
[5, 6, 9]]),
array([[ 1, 2, 10],
[ 3, 4, 10],
[ 5, 6, 10]])]
输出可能有点乱。但这与您提到的所需输出完全一样。为了确保,您可以在下方 运行 查看 result
数组中第一个元素的内容:
print(result[0])
输出
array([[1, 2, 7],
[3, 4, 7],
[5, 6, 7]])
在这种情况下,更容易构建更高维度的对象,然后在完成后修复轴。前两个维度是 b 的长度和 a 的长度。第三个维度是a加1的每一行的元素个数,然后我们就可以用广播来填充这个数组了
x, y = a.shape
z, = b.shape
result = np.empty((z, x, y + 1))
result[...,:y] = a
result[...,y] = b[:,None]
此时,要获得您要求的确切答案,您需要交换前两个轴,然后将这两个轴合并为一个轴。
result.swapaxes(0, 1).reshape(-1, y + 1)
一个小时后。 . . .
我聪明了一点,意识到我不需要交换轴。这也有一个很好的好处,即结果是一个连续的数组。
def convert1d(a, b):
x, y = a.shape
z, = b.shape
result = np.empty((x, z, y + 1))
result[...,:y] = a[:,None,:]
result[...,y] = b
return result.reshape(-1, y + 1)
我有 2 个 numpy 数组,一个是二维的,另一个是一维的,例如:
import numpy as np
a = np.array(
[
[1, 2],
[3, 4],
[5, 6]
]
)
b = np.array(
[7, 8, 9, 10]
)
我想获取 a
和 b
中元素的所有可能组合,将 a
视为一维数组,以便它保留 [=12= 中的行] 完好无损,但也将 a
中的行与 b
中的项目连接起来。它看起来像这样:
>>> combine1d(a, b)
[ [1 2 7] [1 2 8] [1 2 9] [1 2 10]
[3 4 7] [3 4 8] [3 4 9] [3 4 10]
[5 6 7] [5 6 8] [5 6 9] [5 6 10] ]
我知道对此有缓慢的解决方案(如 for
循环),但我需要一个快速的解决方案,因为我正在处理具有数百万整数的数据集。
有什么想法吗?
这是非常“透明胶带”的解决方案:
import numpy as np
a = np.array(
[
[1, 2],
[3, 4],
[5, 6]
]
)
b = np.array(
[7, 8, 9, 10]
)
z = []
for x in b:
for y in a:
z.append(np.append(y, x))
np.array(z).reshape(3, 4, 3)
您需要使用np.c_
附加以连接两个数据框。我还使用 np.full
生成第二个数组的一列 (b
)。结果如下:
result = [np.c_[a, np.full((a.shape[0],1), x)] for x in b]
result
输出
[array([[1, 2, 7],
[3, 4, 7],
[5, 6, 7]]),
array([[1, 2, 8],
[3, 4, 8],
[5, 6, 8]]),
array([[1, 2, 9],
[3, 4, 9],
[5, 6, 9]]),
array([[ 1, 2, 10],
[ 3, 4, 10],
[ 5, 6, 10]])]
输出可能有点乱。但这与您提到的所需输出完全一样。为了确保,您可以在下方 运行 查看 result
数组中第一个元素的内容:
print(result[0])
输出
array([[1, 2, 7],
[3, 4, 7],
[5, 6, 7]])
在这种情况下,更容易构建更高维度的对象,然后在完成后修复轴。前两个维度是 b 的长度和 a 的长度。第三个维度是a加1的每一行的元素个数,然后我们就可以用广播来填充这个数组了
x, y = a.shape
z, = b.shape
result = np.empty((z, x, y + 1))
result[...,:y] = a
result[...,y] = b[:,None]
此时,要获得您要求的确切答案,您需要交换前两个轴,然后将这两个轴合并为一个轴。
result.swapaxes(0, 1).reshape(-1, y + 1)
一个小时后。 . . .
我聪明了一点,意识到我不需要交换轴。这也有一个很好的好处,即结果是一个连续的数组。
def convert1d(a, b):
x, y = a.shape
z, = b.shape
result = np.empty((x, z, y + 1))
result[...,:y] = a[:,None,:]
result[...,y] = b
return result.reshape(-1, y + 1)