По моему мнению ...
@ Ответ Ноля более прост и должен быть подходом goto.Но я не мог не предоставить альтернативу Numpy.
i, u = pd.factorize(df.cluster_id)
a = np.zeros(len(u), np.bool8)
np.logical_or.at(a, i, df.dummy.values)
df.assign(dummpy_display=a[i])
cluster_id dummy dummpy_display
0 1 False True
1 1 True True
2 1 True True
3 2 False False
4 2 False False
5 3 False True
6 3 True True
Разбивка
pandas.factorize
создает массив целых чисел, представляющих уникальные значения в df.cluster_id
i, u = pd.factorize(df.cluster_id)
print(f"factorization (i): {[*i]}\nunique values (u): {[*u]}")
factorization (i): [0, 0, 0, 1, 1, 2, 2]
unique values (u): [1, 2, 3]
Затем мы инициализируем False
значения для каждого уникального cluster_id
a = np.zeros(len(u), np.bool8)
print(f"accumulated `or` init (a): {[*a]}")
accumulated `or` init (a): [False, False, False]
Затем используем функцию np.logical_or.at
для накопления с использованием логики or
с учетом заданных индексов и логических значений
np.logical_or.at(a, i, df.dummy.values)
print(f"accumulated `or` post (a): {[*a]}")
print(f"broadcast over factorization (a[i]):\n {[*a[i]]}")
accumulated `or` post (a): [True, False, True]
broadcast over factorization (a[i]):
[True, True, True, False, False, True, True]
Давайте посмотрим глубже.Я переберу и покажу эволюцию того, что происходит с групповой переменной накопления a
a = [False, False, False]
print(f"accumulate `or` init (a): {a}", end='\n\n')
d = df.assign(i=i, a=None)[['cluster_id', 'i', 'dummy', 'a']]
for j in d.index:
a[d.at[j, 'i']] |= d.at[j, 'dummy']
d.at[j, 'a'] = [*a]
d
cluster_id i dummy a
at ↓ ⇩ or a[0] ⇩
0 1 0 False [False, False, False]
╭──────────⤴
at ↓ ⇩ or a[0] == ⇩
1 1 0 True [True, False, False]
╭──────────⤴
at ↓ ⇩ or a[0] == ⇩
2 1 0 True [True, False, False]
╭─────────────────⤴
at ↓ ⇩ or a[1] == ⇩
3 2 1 False [True, False, False]
╭─────────────────⤴
at ↓ ⇩ or a[1] == ⇩
4 2 1 False [True, False, False]
╭────────────────────────⤴
at ↓ ⇩ or a[2] == ⇩
5 3 2 False [True, False, False]
╭────────────────────────⤴
at ↓ ⇩ or a[2] == ⇩
6 3 2 True [True, False, True]
И то же вещание, которое мы показали выше
print(f"result (a): {a}\nbroadcasted (a[i]):\n {[a[j] for j in i]}")
result (a): [True, False, True]
broadcasted (a[i]):
[True, True, True, False, False, True, True]