Настройка
df = pd.DataFrame([
[1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1], # No 50s
[1, 0, 0, 0, 1, 1, 50, 0, 0, 0, 1], # One 50
[1, 50, 0, 0, 1, 50, 50, 0, 0, 0, 1], # Three 50s but 2 are consecutive
[1, 50, 0, 0, 1, 1, 50, 0, 0, 0, 1], # Two 50s
])
df
0 1 2 3 4 5 6 7 8 9 10
0 1 0 0 0 1 1 0 0 0 0 1
1 1 0 0 0 1 1 50 0 0 0 1
2 1 50 0 0 1 50 50 0 0 0 1
3 1 50 0 0 1 1 50 0 0 0 1
Используйте logical_and
с его accumulate
методом
np.logical_and
возьмет оператор and
и применит его к группе логических значений. Часть accumulate
говорит о том, чтобы продолжать применять ее, и по мере отслеживания самой последней and
всех предыдущих логических величин. Указав axis=1
, я говорю сделать это для каждой строки. Это возвращает массив логических значений, где строки истинны, пока мы не достигнем значения 50
. Затем я проверяю, есть ли пятьдесят с all(1)
. Правильное умножение дает суммы всех значений, а не 50 до первых 50 ... для каждой строки.
d = np.logical_and.accumulate(df.ne(50), axis=1)
df.mul(d).mul(~d.all(1), 0).sum(1)
0 0
1 3
2 1
3 1
dtype: int64
Объединить, чтобы получить новый столбец
d = np.logical_and.accumulate(df.ne(50), axis=1)
df.assign(answer=df.mul(d).mul(~d.all(1), 0).sum(1))
0 1 2 3 4 5 6 7 8 9 10 asnswer
0 1 0 0 0 1 1 0 0 0 0 1 0
1 1 0 0 0 1 1 50 0 0 0 1 3
2 1 50 0 0 1 50 50 0 0 0 1 1
3 1 50 0 0 1 1 50 0 0 0 1 1
Если ты хочешь быть полностью раздутым Numpy
v = df.values
a = np.logical_and.accumulate(v != 50, axis=1)
df.assign(answer=(v * (a & ~a.all(1, keepdims=True))).sum(1))
0 1 2 3 4 5 6 7 8 9 10 asnswer
0 1 0 0 0 1 1 0 0 0 0 1 0
1 1 0 0 0 1 1 50 0 0 0 1 3
2 1 50 0 0 1 50 50 0 0 0 1 1
3 1 50 0 0 1 1 50 0 0 0 1 1