#python #pandas #dataframe
Вопрос:
Входные
У меня есть фрейм данных с несколькими столбцами.
proof_path =
#1 X Y #2 X_ Z #3 W Z_ #4 W_ Y_
0 p1 a b p2 a c p2 a c p3 a b
1 p1 a b p2 a c p3 a c p1 a b
2 p1 a b p2 a d p3 e d p4 e b
В приведенном выше фрейме данных я хочу проверить, дублируется ли каждая строка между [#1, X, Y]
, [#2, X_, Z]
, [#3, W, Z_]
, и [#4, W_, Y_]
.
Например, в строках, соответствующих индексу 0, [#2, X_, Z]
и [#3, W_, Z_]
перекрывающихся с [P2, a, c]
. Кроме того, [#1, X, Y]
и [#4, W_, Y_]
в строке, соответствующей индексу 1, перекрываются [P1, a, b]
. Я собираюсь удалить строки, которые перекрываются между этими несколькими значениями, из этого фрейма данных.
Мой желаемый результат таков
выход
proof_path =
#1 X Y #2 X_ Z #3 W Z_ #4 W_ Y_
2 p1 a b p2 a d p3 e d p4 e b
И я попытался сделать следующее.
triple_size = 3
for depth in range(int(len(proof_path.columns)/triple_size)-1):
for i in range(1, int(len(proof_path.columns)/triple_size)-depth):
current_rComp = proof_path.iloc[:, depth*size:(depth 1)*triple_size]
next_rComp = proof_path.iloc[:, (depth i)*size:(depth i 1)*triple_size]
current_rComp.columns = ['pred', 'subj', 'obj']
next_rComp.columns = ['pred', 'subj', 'obj']
proof_path = proof_path[current_rComp.ne(next_rComp).any(axis=1)]
Хотя эти методы смогли достичь желаемых результатов, они неэффективны, генерируя подмножество proof_path
для каждой итерации. Есть ли простой способ выполнить эти задачи?
Комментарии:
1. Было бы проще, если бы вы сначала прочитали фрейм данных только в четыре столбца? например
#1, X, Y
, является ли первый столбец#2, X_, Z
вторым и т. Д.
Ответ №1:
Чтобы избежать вложенных циклов, вы можете использовать наборы: для каждой строки поместите четыре тройки значений в набор. Количество элементов в наборе-это количество уникальных троек. Затем вы можете использовать это количество уникальных троек в качестве маски для выбора строк:
import numpy as np
proof_path['n_unique_triples'] =
proof_path.apply(lambda row: len(set((tuple(row[0:3]),
tuple(row[3:6]),
tuple(row[6:9]),
tuple(row[9:12])))), axis=1)
df_select = proof_path[proof_path.n_unique_triples == 4]
df_select
#1 X Y #2 X_ Z #3 W Z_ #4 W_ Y_ n_unique_triples
2 p1 a b p2 a d p3 e d p4 e b 4