Python/Numpy中组的值切换器

ni65a41a  于 2022-11-10  发布在  Python
关注(0)|答案(2)|浏览(170)

我有一份清单:

groups = ['A', 'A', 'A', 'B', 'B', 'C', 'C', 'D']

我需要将每个值Map为具有如下所示的输出,独立于其中的组和元素的数量:

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

每次更改组时,输出中的值都应该切换。

yptwkmov

yptwkmov1#

使用python

使用列表理解和Python3.8+的海象运算符:

groups = ['A', 'A', 'A', 'B', 'B', 'C', 'C', 'D']

flag = 0

out = [flag if a==b else (flag:=1-flag) for a, b in zip(groups, groups[:1]+groups)]

itertools

from itertools import groupby, chain

out = list(chain.from_iterable([i%2]*len(list(g))
           for i, (_, g) in enumerate(groupby(groups))))

产出:

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

使用pandas

import pandas as pd

out = pd.factorize(groups)[0]%2

产出:

array([0, 0, 0, 1, 1, 0, 0, 1])

或者:

s = pd.Series(groups)
out = (s.ne(s.shift(fill_value=s[0]))
       .cumsum().mod(2).tolist()
       )

产出:

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

使用numpy

import numpy as np

out = np.cumsum(groups != np.r_[groups[:1], groups[:-1]])%2

产出:

array([0, 0, 0, 1, 1, 0, 0, 1])
svmlkihl

svmlkihl2#

这里有另一个O(N)解决方案:

def value_switcher(groups):
    if not groups:
        return groups
    new_groups = [0]
    for i in range(1, len(groups)):
        if groups[i-1] != groups[i]:
            if new_groups[i-1] == 0:
                new_groups.append(1)
            else:
                new_groups.append(0)
        else:
            new_groups.append(new_groups[i-1])
    return new_groups

我对它进行了如下测试:

groups = ['A', 'A', 'A', 'B', 'B', 'C', 'C', 'D']
assert value_switcher(groups) == [0, 0, 0, 1, 1, 0, 0, 1]
groups = ['A']
assert value_switcher(groups) == [0]
groups = ['B', 'A', 'B', 'B', 'A']
assert value_switcher(groups) == [0, 1, 0, 0, 1]
groups = []
assert value_switcher(groups) == []
groups = None
assert value_switcher(groups) is None

相关问题