df = pd.DataFrame([["A", "AA", "AAA", "found"],
["A", "AB", "ABA", "not found"],
["A", "AB", "ABB", "not found"],
["B", "BA", "BAA", "not found"],
["B", "BB", "BBA", "not found"],
["C", "CA", "CAA", "not found"],
["C", "CB", "CBA", "found"],
["C", "CB", "CBA", "not found"]], columns=["col_a", "col_b", "col_c", "where"])
col_a col_b col_c where
0 A AA AAA found
1 A AB ABA not found
2 A AB ABB not found
3 B BA BAA not found
4 B BB BBA not found
5 C CA CAA not found
6 C CB CBA found
7 C CB CBA not found
8 C CB CBB not found
Мне нужно переназначить значения на основе col_a и col_b при условии: если в любой строке с уникальной комбинацией в col_a и col_b "найдено", назначьте ее каждой строке в этой комбинации независимо от других столбцов (например, col_c)
Я пытался прокрутить его, он работает, но неэлегантно и неэффективно.
unique_col_a = df["col_a"].unique()
for bus in unique_col_a:
unique_pdus = df[df["col_a"] == bus]["col_b"].unique()
for pdu in unique_pdus:
bus_pdus_found = df[(df["col_a"] == bus) & (df["col_b"] == pdu) & (df["where"] == "found")]
if len(bus_pdus_found) > 0:
df.loc[(df["col_a"] == bus) & (df["col_b"] == pdu) & (df["where"] != "found"), "where"] = "found"
Таким образом, ожидаемый результат будет примерно таким:
col_a col_b col_c where
0 A AA AAA found
1 A AB ABA not found
2 A AB ABB not found
3 B BA BAA not found
4 B BB BBA not found
5 C CA CAA not found
6 C CB CBA found
7 C CB CBA found
8 C CB CBB found
Спасибо за вашу помощь! Очень ценю это
Конструктор вашего фрейма данных не совпадает с вашим входным фреймворком (отсутствует одна строка)
Предполагая, что столбец where
содержит только значения found, not found
, вы можете сгруппировать фрейм данных по col_a, col_b
и преобразовать where
с помощью min
. Этот подход работает, потому что found
всегда меньше, чем not found
по алфавиту:
df['where'] = df.groupby(['col_a', 'col_b'])['where'].transform('min')
Если столбец where
содержит и другие значения, вот более общее решение:
m = df['where'].eq('found').groupby([df['col_a'], df['col_b']]).transform('any')
df.loc[m, 'where'] = 'found'
Результат
col_a col_b col_c where
0 A AA AAA found
1 A AB ABA not found
2 A AB ABB not found
3 B BA BAA not found
4 B BB BBA not found
5 C CA CAA not found
6 C CB CBA found
7 C CB CBA found
8 C CB CBB found
Это действительно умно. К сожалению, могут быть и другие сообщения в виде строк
@DisplayedName Я отредактировал ответ, указав более общее решение.
Чтобы уточнить, вы ищете способ пометить значения col_c, которые появляются только один раз в фрейме данных?