在python中对数组列表进行分类

Posted

技术标签:

【中文标题】在python中对数组列表进行分类【英文标题】:Categorizing the list of array in python 【发布时间】:2012-05-24 22:02:26 【问题描述】:

我正在帮助我的朋友在 python 中做逻辑算法,但我还没有找到最好的解决方案。

首先,我有一个数组列表:

x = array[0,1,2,3,4,3,2,3,-2,-4,-7,2,2]

他想对 x 进行分类,所以输出变成这样:

array([0,1,2,3,4]) # increasing value
array([4,3,2]) #decreasing value
array([2,3]) # increasing value
array([3,-2,-4,-7]) #decreasing value
array([-7,2]) # increasing value
array([2,2])  # remain_the_same_value

规则很简单:

    如果该值不断增加(如上例:0,1,2,3,4),则将其放入一个数组中 如果该值不断减小(如上例:3、-2、-4、-7),则将其放入一个数组中 但是,如果值模式发生突然变化,例如上面的示例:从增加的值 (0,1,2,3,4) 突然下一个值正在减少。将制作新数组并放入最后一个增加的值(4)并监视下一个值,无论它是否是减少值。如果是,它们将被放在一个数组中。示例 :array([4,3,2]) 如果值保持不变(如上例,从 2 到 2)。它们将被放在一个数组中。

这就是我目前为止的结果,但距离解决方案还很远

#categorize which types of input
if len(x) > 2 :
    for i in range(len(x)) :
        if (x[i+1]-x[i]) > 0 and i+i < len(x) : # for increasing x value

        elif (x[i+1]-x[i]) < 0 and i+i < len(x) : # for decreasing x value

        elif (x[i+1]-x[i]) == 0 and i+i < len(x) : # for foward direction of vehicle

        else :
            print 'ERROR : check the input coordinates once again!'

最好的问候,

格伦

【问题讨论】:

我不明白这部分:array([3,-2]) #decreasing value array([-2,-4,-7]) #decreasing value它们都在减少,为什么它们不同? @ jamylak :是的,你是对的。我在那里犯了一个错误。我会马上修好。谢谢贾米拉克 【参考方案1】:

首先我想说我不明白你的问题的一部分,

array([3,-2]) #decreasing value
array([-2,-4,-7]) #decreasing value

为什么这些是分开的?

到目前为止,我将发布我的答案,该答案给出了除了该部分之外的正确结果,因为我看不到它背后的逻辑。为简单起见,此示例使用列表和元组,但您可以根据需要将其更改为使用数组。

>>> from itertools import groupby
>>> data = [0,1,2,3,4,3,2,3,-2,-4,-7,2,2]
>>> def slope(a,b): #Returns 1 for inc, 0 for equal and -1 for dec
        return (a > b) - (a < b) 

>>> def groups(nums):
        for k,v in groupby(zip(nums,nums[1:]), lambda (x,y): slope(x,y)):
            yield next(v) + tuple(y for x,y in v) #Using itertools.chain this can be written as tuple(chain(next(v),(y for x,y in v)))


>>> list(groups(data))
[(0, 1, 2, 3, 4), (4, 3, 2), (2, 3), (3, -2, -4, -7), (-7, 2), (2, 2)]

【讨论】:

+1,但我相信 cmp 只保证它返回正数、负数或零。 docs.python.org/library/functions.html#cmp。另外,你可以只写“cmp”而不是 lambda (x, y): cmp(x, y)! @Anonymous 那有什么问题?它要么增加,要么减少,要么保持不变。 对于不同的比较,它可能不会返回相同的数字。例如, cmp(6, 3) 可能是 3 而 cmp(3, 1) 可能是 2。这将导致您的 groupby 无法加入这些运行。 @Anonymous 我不能只写cmp,因为这会将每一对作为一个元组,我会将一个元组传递给 cmp,试试它不起作用。你能告诉我一个不像你说的那样有效的例子吗? @jamlak,感谢您对我们的启发。我以前从未使用过groupby,现在我会花时间研究它。我也会给你+1【参考方案2】:

我找到所有运行变化的地方,然后生成包括两个端点的运行。

def sgn(x):
  return (x > 0) - (x < 0)

def categorize(xs):
  endpoints = [0]
  endpoints.extend(i for i, x in enumerate(xs[1:-1], 1)
                   if sgn(x - xs[i - 1]) != sgn(xs[i + 1] - x))
  endpoints.append(len(xs) - 1)
  for e0, e1 in zip(endpoints, endpoints[1:]):
    yield xs[e0:e1 + 1]

print list(categorize([0,1,2,3,4,3,2,3,-2,-4,-7,2,2]))
print list(categorize([0, 1, 2, 3]))
print list(categorize([0]))

【讨论】:

【参考方案3】:

这个使用 numpy 怎么样,它同时解决了你的第二个问题。

将 numpy 导入为 np x=(0, 1, 2, 3, 4, 3, 2, 3, -2, -4, -7, 2, 2) y=范围(13) #一阶微分,求斜率 dx = list((np.diff(x)>0)*1) #一阶差分丢失了第一个值,但我们总是想保留它 #只需决定它是低于还是高于第二个值 d0=((x[0]-x[1])>0)*1 #将一阶微分添加到二阶微分(峰值) ddx = [d0,]+list(np.abs(np.diff(dx))) p=0 rx=[] ry=[] 对于 enumerate(ddx) 中的 n,v: 如果 v==1: rx.append(元组(x[p:n+1])) ry.append(元组(y[p:n+1])) p=n 打印接收 打印

【讨论】:

以上是关于在python中对数组列表进行分类的主要内容,如果未能解决你的问题,请参考以下文章

Python - 对数组列表进行分类第 2 部分

是否有任何算法可以在某些模式中对数组进行分类?

如何在 python 3 中对大量文本进行分类?

如何在 python 的朴素贝叶斯分类器中对用户输入测试集进行分类?

在 Java 中对记录进行分类

如何在python中对没有标题的大型csv信号文件进行分类?