Pandas/NumPy:简洁地标记与掩码匹配的前N个值

Pandas/NumPy:简洁地标记与掩码匹配的前N个值,pandas,numpy,Pandas,Numpy,我有这样一个排序序列: [2, 4, 5, 6, 8, 9] 我想生成另一个长度相同的序列或ndarray,其中前两个奇数和前两个偶数按顺序标记: [0, 1, 2, _, _, 3] \uu值我并不真正关心。它们可以是零 现在我这样做: src = pd.Series([2, 4, 5, 6, 8, 9]) odd = src % 2 != 0 where = np.hstack((np.where(odd)[0][:2], np.where(~odd)[0][:2])) where.so

我有这样一个排序序列:

[2, 4, 5, 6, 8, 9]
我想生成另一个长度相同的序列或ndarray,其中前两个奇数和前两个偶数按顺序标记:

[0, 1, 2, _, _, 3]
\uu
值我并不真正关心。它们可以是零

现在我这样做:

src = pd.Series([2, 4, 5, 6, 8, 9])
odd = src % 2 != 0
where = np.hstack((np.where(odd)[0][:2], np.where(~odd)[0][:2]))
where.sort() # maintain ordering - thanks to @hpaulj
res = np.zeros(len(src), int)
res[where] = np.arange(len(where))

你能做得更简洁些吗?输入永远不会为空,但可能没有赔率或偶数(在这种情况下,结果的长度可能是1、2或3而不是4)。

大问题!我还在探索和学习

到目前为止,我基本上一直坚持您所做的工作,并对效率进行了适当的调整。如果我想到其他酷的东西,我会更新

结论
到目前为止,我已经做了很多努力,没有多大进步

我的答案
快速


备选方案2
没有那么快,但是很有创意

a = src.values
odd = a % 2
res = np.zeros(len(src), int)
b = np.arange(2)
c = b[:, None] == odd
res[(c.cumsum(1) * c <= 2).all(0)] = np.arange(4)
a=src.values
奇数=a%2
res=np.zero(len(src),int)
b=np.arange(2)
c=b[:,无]==奇数

res[(c.cumsum(1)*c顺序重要吗?在你的例子中,2个偶数出现在任何赔率之前,但是
[1,4,5,7,8,9]
产生
[2,0,3,0,1,0]
res[np.sort(where)]=…
是一个简单的解决方法。或者创建一个中间布尔掩码。@hpaulj:好问题。我确实更喜欢排序。我将添加
where.sort()
到我的示例解决方案(使其更加简洁!)。
a = src.values
odd = (a % 2).astype(bool)
rng = np.arange(len(a))

# same reason these are 2, we have 4 below
where = np.append(rng[~odd][:2], rng[odd][:2])
res = np.zeros(len(a), int)

# nature of the problem necessitates that this is 4
res[where] = np.arange(4)
a = src.values
odd = a % 2
res = np.zeros(len(src), int)
b = np.arange(2)
c = b[:, None] == odd
res[(c.cumsum(1) * c <= 2).all(0)] = np.arange(4)
odd = src.values % 2
a = (odd[:, None] == [0, 1])
b = ((a.cumsum(0) * a) <= 2).all(1)
(b.cumsum() - 1) * b
def pir3(src):
    odd = src.values % 2
    a = (odd[:, None] == [0, 1])
    b = ((a.cumsum(0) * a) <= 2).all(1)
    return (b.cumsum() - 1) * b

def pir0(src):
    odd = src.values % 2
    even = 1 - odd
    res = ((odd.cumsum() * odd) < 3) * ((even.cumsum() * even) < 3)
    return (res.cumsum() - 1) * res

def pir2(src):
    a = src.values
    odd = a % 2
    res = np.zeros(len(src), int)
    c = b[:, None] == odd
    res[(c.cumsum(1) * c <= 2).all(0)] = np.arange(4)
    return res

def pir1(src):
    a = src.values
    odd = (a % 2).astype(bool)
    rng = np.arange(len(a))
    where = np.append(rng[~odd][:2], rng[odd][:2])
    res = np.zeros(len(a), int)
    res[where] = np.arange(4)
    return res

def john0(src):
    odd = src % 2 == 0
    where = np.hstack((np.where(odd)[0][:2], np.where(~odd)[0][:2]))
    res = np.zeros(len(src), int)
    res[where] = np.arange(len(where))
    return res

def john1(src):
    odd = src.values % 2 == 0
    where = np.hstack((np.where(odd)[0][:2], np.where(~odd)[0][:2]))
    res = np.zeros(len(src), int)
    res[where] = np.arange(len(where))
    return res