【问题标题】:Numpy indexed array insertionNumpy索引数组插入
【发布时间】:2018-02-25 11:02:29
【问题描述】:

我有 2 个数组,在最后一个轴上具有相同的形状,即:

第一:

   [[6614, 3390, 6327, 7595, 2797],
   [4604, 3392, 4128, 1835, 7397],
   [2268,  367, 7595, 2268, 2546],
   [5450, 5450, 2836, 5450, 4106],
   [8846, 8846, 3666, 8846, 3098],
   [  -1,   -1, 5450,   -1, 5450],
   [  -1,   -1, 8846,   -1, 8846],
   [   0,    0,    0,    0,    0],
   [   0,    0,    0,    0,    0],
   [   0,    0,    0,    0,    0]]

第二个:

   [[4035, 4035, 4035, 1168, 3545],
   [8846, 8846, 8846, 8846, 8846],
   [  -1,   -1,   -1, 8846,   -1]]

假设形状是 (10,5) 和 (3,5)。我想做的是将第二个数组沿第一个轴插入到第一个数组中,但是让第一个数组的每一行都与第二个数组继续,即:(我已将 > 表示为第二个数组)

   [[6614,      3390,     6327,      7595,         2797],
   [4604,       3392,     4128,      1835,         7397],
   [2268,       367,      7595,      2268,         2546],
   [5450,       5450,     2836,      5450,         4106],
   [8846,       8846,     3666,      8846,         3098],
   [<<4035>>,   <<4035>>, 5450,      <<1168>>,     5450],
   [<<8846>>,   <<8846>>, 8846,      <<8846>>,     8846],
   [<<-1>>,     <<-1>>,   <<4035>>,  <<8846>>, <<3545>>],
   [   0,       0,        <<8846>>,     0,     <<8846>>],
   [   0,       0,         <<-1>>,      0,       <<-1>>]]

考虑到第一个数组中总会有足够的空间,另外我还有一个索引列表,可以在其中插入第二个数组:

[5, 5, 7, 5, 7]

np.insert 似乎不接受在特定索引处设置序列,所以我需要接受设置范围的东西。这显然可以用 for 循环解决,但我认为有一个更简单的解决方案。

【问题讨论】:

  • 那么,您没有使用来自[5, 5, 7, 5, 7] 的所有索引,因为第二个数组只有三行?
  • 我正在使用所有索引,请注意有 5 列和 5 个索引。
  • 我不明白你的例子。 [ 0, 0, -1, 0, -1] 来自哪里?
  • 请查看我的更正结果(只有 -1 关闭)。以下是结果的构建方式,逐列获取第二个数组并将其滑入第一个数组,将其定位在索引列表中指定的索引处 ([5, 5, 7, 5, 7])。所以第二个数组的第一列将被插入到第 5 个索引处的第一列。
  • 我已经突出显示了第二个数组在第一个数组中的位置。

标签: python arrays numpy insert concatenation


【解决方案1】:

如果您不介意转换为 pandas DataFrame,这里有一个简单的解决方案:

# Convert arrays to DataFrames
df1 = pd.DataFrame(first)
df2 = pd.DataFrame(second)

# Concatenate the first and second DataFrames
df = pd.concat([df1.replace([-1, 0], np.nan), df2])

df = df.apply(lambda x: pd.Series(x.dropna().values)).fillna(0).astype('int')

# Convert back to numpy array
df = df.as_matrix()

print(df)

[[6614 3390 6327 7595 2797]
 [4604 3392 4128 1835 7397]
 [2268  367 7595 2268 2546]
 [5450 5450 2836 5450 4106]
 [8846 8846 3666 8846 3098]
 [4035 4035 5450 1168 5450]
 [8846 8846 8846 8846 8846]
 [  -1   -1 4035 8846 3545]
 [   0    0 8846    0 8846]
 [   0    0   -1    0   -1]]

【讨论】:

  • 连接只会将第二个数组附加到第一个数组的末尾,考虑到每列的长度不同,它不会进行插入。看看我最初的问题中提到的第三个数组,这是我正在寻找的结果。
  • 它是concatenate,而不是concat。而且它没有做 OP 想要的。
  • 我今天早上用手机做了这个,误解了这个问题。我已经用满足问题的版本对其进行了更新。
  • 比我的解决方案快。谢谢!
【解决方案2】:

可能有一种更有效的方法来做到这一点,但是就这样吧。

如果先转置矩阵,问题会更容易理解:

[[6614 4604 2268 5450 8846   -1   -1    0    0    0]
 [3390 3392  367 5450 8846   -1   -1    0    0    0]
 [6327 4128 7595 2836 3666 5450 8846    0    0    0]
 [7595 1835 2268 5450 8846   -1   -1    0    0    0]
 [2797 7397 2546 4106 3098 5450 8846    0    0    0]]

[[4035 8846   -1]
 [4035 8846   -1]
 [4035 8846   -1]
 [1168 8846 8846]
 [3545 8846   -1]]

然后您只需在正确的偏移量处写入第二行:

import numpy as np
a = np.array([[6614, 3390, 6327, 7595, 2797],
               [4604, 3392, 4128, 1835, 7397],
               [2268,  367, 7595, 2268, 2546],
               [5450, 5450, 2836, 5450, 4106],
               [8846, 8846, 3666, 8846, 3098],
               [  -1,   -1, 5450,   -1, 5450],
               [  -1,   -1, 8846,   -1, 8846],
               [   0,    0,    0,    0,    0],
               [   0,    0,    0,    0,    0],
               [   0,    0,    0,    0,    0]])

b = np.array([[4035, 4035, 4035, 1168, 3545],
   [8846, 8846, 8846, 8846, 8846],
   [  -1,   -1,   -1, 8846,   -1]])

a2 = a.T
b2 = b.T

n = len(b2[0])

for i, offset in enumerate([5, 5, 7, 5, 7]):
  a2[i,offset:offset+n] = b2[i]

print(a2.T)

它输出:

[[6614 3390 6327 7595 2797]
 [4604 3392 4128 1835 7397]
 [2268  367 7595 2268 2546]
 [5450 5450 2836 5450 4106]
 [8846 8846 3666 8846 3098]
 [4035 4035 5450 1168 5450]
 [8846 8846 8846 8846 8846]
 [  -1   -1 4035 8846 3545]
 [   0    0 8846    0 8846]
 [   0    0   -1    0   -1]]

你也可以避免来回转置:

import numpy as np

a = np.array([[6614, 3390, 6327, 7595, 2797],
               [4604, 3392, 4128, 1835, 7397],
               [2268,  367, 7595, 2268, 2546],
               [5450, 5450, 2836, 5450, 4106],
               [8846, 8846, 3666, 8846, 3098],
               [  -1,   -1, 5450,   -1, 5450],
               [  -1,   -1, 8846,   -1, 8846],
               [   0,    0,    0,    0,    0],
               [   0,    0,    0,    0,    0],
               [   0,    0,    0,    0,    0]])

b = np.array([[4035, 4035, 4035, 1168, 3545],
   [8846, 8846, 8846, 8846, 8846],
   [  -1,   -1,   -1, 8846,   -1]])

n = b.shape[0]

for i, offset in enumerate([5, 5, 7, 5, 7]):
  a[offset:offset+n, i] = b[:,i]

print(a)

【讨论】:

  • 是的,这就是我目前使用的。我很好奇 numpy 是否有一个知道如何直接插入它的运算符,而无需 for 循环。如果没有人回答,我最终会接受你的,谢谢。
  • 如果您目前正在使用某些东西,请将其写在您的问题中。它使您更容易理解问题所在。
猜你喜欢
  • 1970-01-01
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 2011-10-23
  • 2011-11-18
  • 1970-01-01
  • 2021-04-17
  • 1970-01-01
相关资源
最近更新 更多