2017-12-18 95 views
3

我想根據以前的值對python列表進行二進制化,如果前一個值較低,則輸出應爲1,如果較高,則輸出爲0。例如:根據以前的值對Python列表進行二值化

[18985.0, 20491.0, 18554.0, 14241.0, 13390.0, 14965.0,] 

應該變成:

[0, 1, 0, 0, 0, 1] 

是否有任何優雅的方式來做到這一點? 在此先感謝!

回答

2

一個列表理解應該工作。

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))] 

您可能想要考慮兩個值相等的情況。

1

您可以使用列表理解和zip函數來實現您想要的結果。我第一次硬編碼值是0由於沒有以前的值進行比較

>>> [0] + [1 if i<j else 0 for i,j in zip(l, l[1:])] 
>>> [0, 1, 0, 0, 0, 1] 
0

numpy的解決方案:需要

import numpy as np 
a=array([18985.0, 20491.0, 18554.0, 14241.0, 13390.0, 14965.0]) 
np.insert(a[1:]>a[:-1],0,False) 
array([False, True, False, False, False, True], dtype=bool) 

插入添加的第一元素,這始終是假。陣列將是

array([True, False, False, False, True], dtype=bool) 

沒有它。如果你想整數,而不是布爾值(即0.1)使用

np.insert(a[1:]>a[:-1],0,False).astype(int) 

你還可以縮短的東西上面的解決方案,如

[0] + [int(i<j) for i,j in zip(l, l[1:])] 

甚至沒有int,如果你不介意的話真和False(也是[0] - >[False])。

0

使用inf作爲第一個比較適當的默認值(它永遠不會是<任意數),並用使用itertools.chain創建開始於inf然後讓你在你的數據上一個項目適當的迭代器。這可能是不錯的,簡潔與mapoperator模塊,如果你不介意的話bool對象作爲你的結果:

>>> 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] 
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] 
相關問題