沿着NumPy数组的行在特定位置插入零行

时间:2016-04-22 17:29:29

标签: python arrays python-2.7 numpy

我有一个两列numpy数组。我想通过第2列的每一行,并取每组2个数字(9.6-0,19.13-9.6等)之间的差异。如果差异> 15,我想为两列插入一行0。我真的只需要在第一列中结束值(我只需要第二列来确定将0放在哪里),所以如果它更容易将它们拆分就可以了。

这是我的输入数组:

 [[0.00 0.00]
 [1.85 9.60]
 [2.73 19.13]
 [0.30 28.70]
 [2.64 38.25]
 [2.29 47.77]
 [2.01 57.28]
 [2.61 66.82]
 [2.20 76.33]
 [2.49 85.85]
 [2.55 104.90]
 [2.65 114.47]
 [1.79 123.98]
 [2.86 133.55]]

它应该变成:

 [[0.00 0.00]
 [1.85 9.60]
 [2.73 19.13]
 [0.30 28.70]
 [2.64 38.25]
 [2.29 47.77]
 [2.01 57.28]
 [2.61 66.82]
 [2.20 76.33]
 [2.49 85.85]
 [0.00 0.00]
 [2.55 104.90]
 [2.65 114.47]
 [1.79 123.98]
 [2.86 133.55]]

6 个答案:

答案 0 :(得分:7)

您可以使用ediff1d中的argmaxinsertnumpy进行一次性投注:

np.insert(arr, np.argmax(np.append(False, np.ediff1d(arr[:,1])>15)), 0, axis=0)

#array([[   0.  ,    0.  ],
#       [   1.85,    9.6 ],
#       [   2.73,   19.13],
#       [   0.3 ,   28.7 ],
#       [   2.64,   38.25],
#       [   2.29,   47.77],
#       [   2.01,   57.28],
#       [   2.61,   66.82],
#       [   2.2 ,   76.33],
#       [   2.49,   85.85],
#       [   0.  ,    0.  ],
#       [   2.55,  104.9 ],
#       [   2.65,  114.47],
#       [   1.79,  123.98],
#       [   2.86,  133.55]])

答案 1 :(得分:6)

假设A为输入数组,这里是一个基于零初始化的矢量化方法 -

# Get indices at which such diff>15 occur 
cut_idx = np.where(np.diff(A[:,1]) > 15)[0]

# Initiaize output array
out = np.zeros((A.shape[0]+len(cut_idx),2),dtype=A.dtype)

# Get row indices in the output array at which rows from A are to be inserted.
# In other words, avoid rows to be kept as zeros. Finally, insert rows from A.
idx = ~np.in1d(np.arange(out.shape[0]),cut_idx + np.arange(1,len(cut_idx)+1))
out[idx] = A

示例输入,输出 -

In [50]: A  # Different from the one posted in question to show variety
Out[50]: 
array([[   0.  ,    0.  ],
       [   1.85,    0.6 ],
       [   2.73,   19.13],
       [   2.2 ,   76.33],
       [   2.49,   85.85],
       [   2.55,  104.9 ],
       [   2.65,  114.47],
       [   1.79,  163.98],
       [   2.86,  169.55]])

In [51]: out
Out[51]: 
array([[   0.  ,    0.  ],
       [   1.85,    0.6 ],
       [   0.  ,    0.  ],
       [   2.73,   19.13],
       [   0.  ,    0.  ],
       [   2.2 ,   76.33],
       [   2.49,   85.85],
       [   0.  ,    0.  ],
       [   2.55,  104.9 ],
       [   2.65,  114.47],
       [   0.  ,    0.  ],
       [   1.79,  163.98],
       [   2.86,  169.55]])

答案 2 :(得分:2)

a=[[0.00, 0.00],
 [1.85, 9.60],
 [2.73, 19.13],
 [0.30, 28.70],
 [2.64, 38.25],
 [2.29, 47.77],
 [2.01, 57.28],
 [2.61, 66.82],
 [2.20, 76.33],
 [2.49, 85.85],
 [2.55, 104.90],
 [2.65, 114.47],
 [1.79, 123.98],
 [2.86, 133.55]]

i=0
while i <len(a)-1:
    if (a[i+1][1]-a[i][1])>15:
        a.insert(i+1,[0,0])
        i=i+1
    i=i+1    

for line in a :
    print line

输出:

[0.0, 0.0]
[1.85, 9.6]
[2.73, 19.13]
[0.3, 28.7]
[2.64, 38.25]
[2.29, 47.77]
[2.01, 57.28]
[2.61, 66.82]
[2.2, 76.33]
[2.49, 85.85]
[0, 0]
[2.55, 104.9]
[2.65, 114.47]
[1.79, 123.98]
[2.86, 133.55]

答案 3 :(得分:1)

这是正确的算法:

arr = [ ... ]
result = []
result.append(arr[0])
for i in range(1, len(arr)):
    if arr[i][1] - arr[i-1][1] > 15:
        result.append([0.0,0.0])
    result.append(arr[i])

print(result)

答案 4 :(得分:1)

可以处理多个填充槽的单个衬垫。在这里,我在OP示例中测试它,并使用一个修改后的值。

In [70]: np.insert(a, np.where(np.diff(a[:,1])>15)[0]+2,0, axis=0)


In [71]: Out[70]: 
array([[   0.  ,    0.  ],
       [   1.85,    9.6 ],
       [   2.73,   19.13],
       [   0.3 ,   28.7 ],
       [   2.64,   38.25],
       [   2.29,  140.  ],   # modified
       [   0.  ,    0.  ],
       [   2.01,   57.28],
       [   2.61,   66.82],
       [   2.2 ,   76.33],
       [   2.49,   85.85],
       [   2.55,  104.9 ],
       [   0.  ,    0.  ],
       [   2.65,  114.47],
       [   1.79,  123.98],
       [   2.86,  133.55]])

使用where代替argmaxColonel's回答)可以处理多个广告位。 +2是必需的,因为diff只有一个,我们正在插入。 ediff1d有更多选项来处理终点。

np.insert有各种填充策略。在这种情况下,它可能会执行与Divakar's回答类似的操作 - 创建out,并将值复制到正确的广告位。

另一个答案使用np.abs()。这可能是必需的,但在我的示例中,在0回退到140之后会添加另一个57行。

答案 5 :(得分:0)

如果numpy没有使用本地方法来做这类事情,我会感到惊讶,但我认为这也会有效:

i = 1
while i < len(lst):
    if abs(lst[i][1] - lst[i-1][1]) > 15:
        lst[i] = [0.0, 0.0]
        # uncomment to change only the second column
        # lst[i][1] = 0.0
        i += 1
    i += 1

输出:

>>> lst
array([[   0.  ,    0.  ],
       [   1.85,    9.6 ],
       [   2.73,   19.13],
       [   0.3 ,   28.7 ],
       [   2.64,   38.25],
       [   2.29,   47.77],
       [   2.01,   57.28],
       [   2.61,   66.82],
       [   2.2 ,   76.33],
       [   2.49,   85.85],
       [   2.55,  104.9 ],
       [   2.65,  114.47],
       [   1.79,  123.98],
       [   2.86,  133.55]])
>>> 
>>> i = 1
>>> while i < len(lst):
...     if abs(lst[i][1] - lst[i-1][1]) > 15:
...         lst[i] = [0.0, 0.0]
...         i += 1
...     i += 1
... 
>>> lst
array([[   0.  ,    0.  ],
       [   1.85,    9.6 ],
       [   2.73,   19.13],
       [   0.3 ,   28.7 ],
       [   2.64,   38.25],
       [   2.29,   47.77],
       [   2.01,   57.28],
       [   2.61,   66.82],
       [   2.2 ,   76.33],
       [   2.49,   85.85],
       [   0.  ,    0.  ],
       [   2.65,  114.47],
       [   1.79,  123.98],
       [   2.86,  133.55]])
>>>