【问题标题】:How to split numpy array into numpy arrays based on columns?如何根据列将 numpy 数组拆分为 numpy 数组?
【发布时间】:2020-04-10 18:00:16
【问题描述】:

如果列的所有值都为零,我想根据列拆分 numpy 数组。如果列序列像样本数组的前两列一样只有 0,则该组应丢弃。

有没有有效的解决方案?

示例输入 numpy 数组:

[[0.   0.   0.   255.   0.   255.   0.   0.   0.  ]
 [0.   0.   0.   255.   0.   255.   0.   0.   0.  ]
 [0.   0.   0.   255.   0.   255.   255. 0.   0.  ]
 [0.   0.   255. 255.   0.   0.     0.   0.   255.]
 [0.   0.   0.   255.   0.   255.   0.   0.   0.  ]
 [0.   0.   0.   255.   0.   255.   0.   0.   0.  ]
 [0.   0.   0.   255.   0.   255.   0.   0.   0.  ]
]

预期输出 numpy 数组:

[[
  [0.    255.]
  [0.    255.]
  [0.    255.]
  [255.  255.]
  [0.    255.]
  [0.    255.]
  [0.    255.]
 ]
 [
  [255. 0.  ]
  [255. 0.  ]
  [255. 255.]
  [0.   0.  ]
  [255. 0.  ]
  [255. 0.  ]
  [255. 0.  ]
 ]
 [
  [0.  ]
  [0.  ]
  [0.  ] 
  [255.] 
  [0.  ]
  [0.  ]
  [0.  ]
 ]
]

【问题讨论】:

  • 你想要一个 numpy 数组的输出吗?如果是这样,shape() 会是什么?

标签: python arrays numpy split


【解决方案1】:

您可以使用itertools.groupby 和列表理解

from itertools import groupby

m = a.any(0)
out = [a[:,[*g]] for k, g in groupby(np.arange(len(m)), lambda x: m[x] != 0) if k]

Out[180]:
[array([[  0, 255],
        [  0, 255],
        [  0, 255],
        [255, 255],
        [  0, 255],
        [  0, 255],
        [  0, 255]]),
 array([[255,   0],
        [255,   0],
        [255, 255],
        [  0,   0],
        [255,   0],
        [255,   0],
        [255,   0]]),
 array([[  0],
        [  0],
        [  0],
        [255],
        [  0],
        [  0],
        [  0]])]

注意a 是您的示例数组


如评论中所述,如果您想丢弃只有一个非零值的列,只需将m 更改为不同的掩码即可处理所有0one non-zero

m = (a != 0).sum(0) > 1    
out = [a[:,[*g]] for k, g in groupby(np.arange(len(m)), lambda x: m[x] != 0) if k]

Out[204]:
[array([[255],
        [255],
        [255],
        [255],
        [255],
        [255],
        [255]]),
 array([[255],
        [255],
        [255],
        [  0],
        [255],
        [255],
        [255]])]

【讨论】:

  • 它按我的预期工作,谢谢!如果只有一个列元素不等于0,是否有可能,你能说我如何丢弃该列吗?
  • 喜欢的列:2, 6, 8(从0开始计数)。你想丢弃它们吗?
  • 是的,如果只有一个值不同于 0。
  • 您实际上不需要额外的掩码,只需更改掩码m 即可同时处理all zeroone non-zero。查看我最新更新的答案
  • @AndyL,谢谢!这就是我想要的。
【解决方案2】:

一种解决方案是利用scipy.ndimage 库来标记具有任何非零元素的列,然后使用这些标签拆分您的数组。

https://docs.scipy.org/doc/scipy/reference/generated/scipy.ndimage.label.html

例如...

import numpy as np
from scipy import ndimage

# convert input string to numpy array
s = '''[[0.   0.   0.   255.   0.   255.   0.   0.   0.  ]
 [0.   0.   0.   255.   0.   255.   0.   0.   0.  ]
 [0.   0.   0.   255.   0.   255.   255. 0.   0.  ]
 [0.   0.   255. 255.   0.   0.     0.   0.   255.]
 [0.   0.   0.   255.   0.   255.   0.   0.   0.  ]
 [0.   0.   0.   255.   0.   255.   0.   0.   0.  ]
 [0.   0.   0.   255.   0.   255.   0.   0.   0.  ]
]'''
X = eval("np.array(%s)" % s.replace('.', ',').replace('\n', ',')).astype(float)

# label continuous columns with any non-zero values
labels, N = ndimage.label((X > 0).any(0))

# display the column splits
for n in range(1, N+1):
    mask = labels == n
    print(X[:, mask])

应该显示...

[[  0. 255.]
 [  0. 255.]
 [  0. 255.]
 [255. 255.]
 [  0. 255.]
 [  0. 255.]
 [  0. 255.]]
[[255.   0.]
 [255.   0.]
 [255. 255.]
 [  0.   0.]
 [255.   0.]
 [255.   0.]
 [255.   0.]]
[[  0.]
 [  0.]
 [  0.]
 [255.]
 [  0.]
 [  0.]
 [  0.]]

【讨论】:

  • 谢谢和抱歉,因为我忘了说没有 scipy。
【解决方案3】:

如果您不能或不想使用 scipy,这也可以:

def twoCols():
    arr = np.array([[0. ,  0.,   0.,   255. ,  0.,   255.,   0.  , 0. ,  0.  ],[0.  , 0. ,  0. ,  255. ,  0.,   255.,   0.  , 0. ,  0.  ],[0.,   0. ,  0.  , 255.,   0.  , 255. ,  255. ,0. ,  0.  ],[0.   ,0. ,  255., 255. ,  0. ,  0. ,    0. ,  0. ,  255.],[0.,   0. ,  0. ,  255. ,  0.,   255. ,  0. ,  0.,   0.  ],[0.,   0. ,  0. ,  255.,   0. ,  255. ,  0. ,  0.,   0.  ],[0.,   0. ,  0. ,  255. ,  0. ,  255. ,  0. ,  0. ,  0.  ]], dtype=np.float64)
    arrs = []   
    for c in range(arr.shape[1]):
        if c == arr.shape[1]-1:
            if sum(arr[:,c]) > 0:
                    arrs.append(arr[:,c:])              
        elif sum(arr[:,c]) > 0 and sum(arr[:,c+1]) > 0:
            arrs.append(arr[:,c:c+2])                           
    return arrs

>>> twoCols()
[array([[   0.,  255.],
       [   0.,  255.],
       [   0.,  255.],
       [ 255.,  255.],
       [   0.,  255.],
       [   0.,  255.],
       [   0.,  255.]]), array([[ 255.,    0.],
       [ 255.,    0.],
       [ 255.,  255.],
       [   0.,    0.],
       [ 255.,    0.],
       [ 255.,    0.],
       [ 255.,    0.]]), array([[   0.],
       [   0.],
       [   0.],
       [ 255.],
       [   0.],
       [   0.],
       [   0.]])]

【讨论】:

  • 如何分别访问这些数组? 'for _ in arrs' 返回一维数组多维数组。
  • arrs 只是一个普通的 python 列表,因此您可以使用 arrs[0]、arrs[1] 等访问每个数组...
【解决方案4】:

这与您要求的格式不同。但我喜欢优雅:

import numpy as np
data = np.array([
 [0.,   0.,   0.,   255.,   0.,   255.,   0.,   0.,   0.  ],
 [0.,   0.,   0.,   255.,   0.,   255.,   0.,   0.,   0.  ],
 [0.,   0.,   0.,   255.,   0.,   255.,   255., 0.,   0.  ],
 [0.,   0.,   255., 255.,   0.,   0.,     0.,   0.,   255.],
 [0.,   0.,   0.,   255.,   0.,   255.,   0.,   0.,   0.  ],
 [0.,   0.,   0.,   255.,   0.,   255.,   0.,   0.,   0.  ],
 [0.,   0.,   0.,   255.,   0.,   255.,   0.,   0.,   0.  ],
])
a=np.zeros((data.shape[0]))            
cols = np.any(data!=0, axis=0)
for i, c in enumerate(cols):
    if c:
        a = np.column_stack((a, data[:,i]))
a = a[:,1:]
print(a)

输出:


[[  0. 255. 255.   0.   0.]
 [  0. 255. 255.   0.   0.]
 [  0. 255. 255. 255.   0.]
 [255. 255.   0.   0. 255.]
 [  0. 255. 255.   0.   0.]
 [  0. 255. 255.   0.   0.]
 [  0. 255. 255.   0.   0.]]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 2016-06-06
    相关资源
    最近更新 更多