Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-切片数组,直到满足特定条件_Python_Arrays_Numpy_Slice - Fatal编程技术网

Python-切片数组,直到满足特定条件

Python-切片数组,直到满足特定条件,python,arrays,numpy,slice,Python,Arrays,Numpy,Slice,我需要从给定的索引中切片一个数组,直到满足某个条件 >>> a = numpy.zeros((10), dtype='|S1') >>> a[2] = 'A' >>> a[4] = 'X' >>> a[8] = 'B' >>> a array(['', '', 'A', '', 'X', '', '', '', 'B', ''], dtype='|S1') 例如,对于上面的数组,我想要一个从给定索引到两个

我需要从给定的索引中切片一个数组,直到满足某个条件

>>> a = numpy.zeros((10), dtype='|S1')
>>> a[2] = 'A'
>>> a[4] = 'X'
>>> a[8] = 'B'
>>> a
array(['', '', 'A', '', 'X', '', '', '', 'B', ''], dtype='|S1')
例如,对于上面的数组,我想要一个从给定索引到两个方向上的第一个非零值的子集。例如,对于索引值2、4、8,结果将是:

['', '', A, '']      # 2
['', X, '', '', '']  # 4
['', '', '', B, '']  # 8

关于使用numpy API实现这一点的最简单方法有什么建议吗?学习python和numpy,如有任何帮助,将不胜感激。谢谢

首先想到的是两个循环。类似这样的方法会奏效:

'''Given an array and an index...'''
def getNoneSlice(a, i):

    # get the first non-None index before i
    start = 0
    for j in xrange(i - 1, -1, -1):
        if a[j] is not None: # or whatever condition
            start = j + 1
            break

    # get the first non-None index after i
    end = len(a) - 1
    for j in xrange(i + 1, len(a)):
        if a[j] is not None: # or whatever condition
            end = j - 1
            break

    # return the slice
    return a[start:end + 1]

如果您这样设置问题:

import numpy
a = numpy.zeros((10), dtype=str)
a[2] = 'A'
a[4] = 'X'
a[8] = 'B'
您可以轻松获得非空字符串的索引,如下所示:

i = numpy.where(a!='')[0]  # array([2, 4, 8])
或者,
numpy.argwhere(…)
也可以正常工作

然后,您可以使用此阵列进行切片:

out2 = a[:i[1]]        # 2   ['' '' 'A' '']
out4 = a[i[0]+1:i[2]]  # 4   ['' 'X' '' '' '']

等等。

这是一项针对屏蔽阵列的工作,numpy.ma有许多用于处理子集的函数

a = np.zeros((10), dtype=str)
a[2] = 'A'
a[4] = 'X'
a[8] = 'B'
让我们屏蔽非空元素:

am=np.ma.masked_where(a!='', a)
np.ma.notmasked\u continuous
遍历数组(非常有效),并查找数组未被屏蔽的所有连续元素片:

slices = np.ma.notmasked_contiguous(am)
[slice(0, 1, None), slice(3, 3, None), slice(5, 7, None), slice(9, 9, None)]
例如,数组在元素5和7之间连续为空。 现在,您只需加入感兴趣的切片,首先获得每个切片的起始索引:

slices_start = np.array([s.start for s in slices])
然后获得要查找的索引的位置:

slices_start.searchsorted(4) #4
Out: 2
所以您需要第1和第2部分: a[切片[1]。开始:切片[2]。停止+1] 数组(['',X','','',''), 数据类型=“| S1”)

或者让我们试试8:

i = slices_start.searchsorted(8)
a[slices[i-1].start:slices[i].stop+1]
Out: array(['', '', '', 'B', ''], 
  dtype='|S1')

If可能应该在ipython中使用它来更好地理解它。

注意,这可以在纯python中使用itertools和functools干净地完成

import functools, itertools
arr = ['', '', 'A', '', 'X', '', '', '', 'B', '']

f = functools.partial(itertools.takewhile, lambda x: not x)
def g(a, i):
    return itertools.chain(f(reversed(a[:i])), [a[i]], f(a[i+1:]))
我们将f定义为子迭代器,通过查找直到元素的计算结果为true,将g定义为将其应用于索引前列表的反向区域和索引后列表的组合

这将返回可以转换为包含结果的列表的生成器

>>> list(g(arr, 2))
['', '', 'A', '']
>>> list(g(arr, 4))
['', 'X', '', '', '']
>>> list(g(arr, 8))
['', '', '', 'B', '']

你能澄清你的问题吗?“直到两个方向上的第一个非None值”是什么意思?在尝试确定非None数组项的索引时,使用
对象
数组(不是很常见,内存效率也不是很高)这一事实提出了一个特殊的问题。能说服您使用固定字节的数据类型吗?如果您致力于
对象
dtype,那么当typecast为
bool
时,任何“非None”都将计算为
true
?这两种方法中的任何一种都会大大简化事情。@Paul我正在使用
对象
数组来存储单个字符串。基本上,我只需要一个
char
数组。有没有一种替代的
dtype
我可以使用
dtype
?@armandino:use
dtype='|S1'
(或者干脆
dtype=str
)来处理单个字符串。@armandino:另外,如果你还没有注意到的话,在使用
dtype='S1'
时,你可能需要numpy.zero(…)而不是numpy.empty(…)。该解决方案非常有效(+1)。不过,我希望有一个
numpy
方法来解决类似的问题。我投了反对票,因为这对于大型稀疏阵列来说效率很低。使用其他答案的简单方法。是的,Steabert,同意。。。至少我学到了一些新的东西,我担心它不起作用。我得到了
[''A'][''X'][''B']
当我回答这个问题时,它没有空字符串,它没有空字符串。如果非零方法与“None”一起工作,则表示感谢Paul。看起来像是我要找的,很有趣,安德里亚。谢谢你的解释。非常感谢!
>>> list(g(arr, 2))
['', '', 'A', '']
>>> list(g(arr, 4))
['', 'X', '', '', '']
>>> list(g(arr, 8))
['', '', '', 'B', '']