【发布时间】:2017-12-18 07:45:52
【问题描述】:
我想根据前一个值对 python 列表进行二值化,如果前一个值较低,则输出应为 1,如果较高,则输出应为 0。示例:
[18985.0, 20491.0, 18554.0, 14241.0, 13390.0, 14965.0,]
应该变成:
[0, 1, 0, 0, 0, 1]
有什么优雅的方法可以做到这一点吗? 提前致谢!
【问题讨论】:
我想根据前一个值对 python 列表进行二值化,如果前一个值较低,则输出应为 1,如果较高,则输出应为 0。示例:
[18985.0, 20491.0, 18554.0, 14241.0, 13390.0, 14965.0,]
应该变成:
[0, 1, 0, 0, 0, 1]
有什么优雅的方法可以做到这一点吗? 提前致谢!
【问题讨论】:
列表推导应该可以工作。
A = [18985.0, 20491.0, 18554.0, 14241.0, 13390.0, 14965.0]
A = [0] + [1 if A[i] > A[i-1] else 0 for i in range(1, len(A))]
您可能需要考虑两个值相等的情况。
【讨论】:
您可以使用列表推导和zip 函数来实现您想要的结果。我将第一个值硬编码为0,因为没有以前的值可以比较
>>> [0] + [1 if i<j else 0 for i,j in zip(l, l[1:])]
>>> [0, 1, 0, 0, 0, 1]
【讨论】:
map解决方案:
vals = [18985.0, 20491.0, 18554.0, 14241.0, 13390.0, 14965.0]
map(
lambda (ind, x):
1 if vals[ind] > vals[ind - 1] and ind != 0 else 0,
enumerate(vals)
)
输出:
[0, 1, 0, 0, 0, 1]
【讨论】:
使用inf 作为第一次比较的适当默认值(它永远不会是< 任何数字),并使用使用itertools.chain 创建一个从inf 开始的适当迭代器,然后为您提供上一个数据中的项目。如果您不介意 bool 对象作为您的结果,那么使用 map 和 operator 模块可以很简洁:
>>> from itertools import chain
>>> inf = float('inf')
>>> import operator as op
>>> list(map(op.lt, data, chain((inf,), data)))
[True, False, True, True, True, False]
这也可以通过使用zip 的列表理解来完成,尽管它开始变得笨拙:
>>> [prev < curr for curr, prev in zip(data, chain((inf,), data))]
[False, True, False, False, False, True]
但它允许更方便地转换为int:
>>> [int(prev < curr) for curr, prev in zip(data, chain((inf,), data))]
[0, 1, 0, 0, 0, 1]
【讨论】: