#pandas #dataframe #comparison #rows #partial
#pandas #фрейм данных #сравнение #строки #частичное
Вопрос:
Я пытаюсь добавить столбец к фрейму данных df1, в котором указывается, отображается ли строка в df1 во втором фрейме данных df2. Как правило, это было бы довольно просто, однако я действительно хочу, чтобы совпадение 4/5 учитывалось так же, как совпадение столбцов 5/5.
То есть запись в новом столбце, добавленном в df1, озаглавленная «In_df2», была бы равна 1, если бы было точное совпадение в 5 соответствующих столбцах (из 9) или совпадения в 4/5 соответствующих столбцов. Допустим, это df1 (с удаленными посторонними столбцами).
df1_rows = [['555555555', 'M', 'Mike', 'Smith', '1970-01-01'], ['999999999', 'F', 'Jane', 'Won&', '1980-01-01'], ['111111111', 'M', 'Steve', 'Patel', '1990-01-01']]
df1 = pd.DataFrame(df1_rows, columns = ['SSN', 'sex', 'first_name', 'last_name', 'dob'])
SSN sex first_name last_name dob
0 555555555 M Mike Smith 1970-01-01
1 999999999 F Jane Won& 1980-01-01
2 111111111 M Steve Patel 1990-01-01
И скажите, что это df2.
df2_rows = [['222222222', 'F', 'Steve', 'Patel', '1990-01-01'], ['555555555', 'M', 'Mike', 'Smith', '1970-01-01'], ['999999999', 'F', 'Jeff', 'Won&', '1980-01-01']]
df2 = pd.DataFrame(df2_rows, columns = ['SSN', 'sex', 'first_name', 'last_name', 'dob'])
df2
SSN sex first_name last_name dob
0 222222222 F Steve Patel 1990-01-01
1 555555555 M Mike Smith 1970-01-01
2 999999999 F Jeff Won& 1980-01-01
Затем он должен вернуть следующее:
df3_rows = [['555555555', 'M', 'Mike', 'Smith', '1970-01-01', 1], ['999999999', 'F', 'Jane', 'Won&', '1980-01-01', 1], ['111111111', 'M', 'Steve', 'Patel', '1990-01-01', 0]]
df3 = pd.DataFrame(df3_rows, columns = ['SSN', 'sex', 'first_name', 'last_name', 'dob', 'In_df2'])
df3
SSN sex first_name last_name dob In_df2
0 555555555 M Mike Smith 1970-01-01 1
1 999999999 F Jane Won& 1980-01-01 1
2 111111111 M Steve Patel 1990-01-01 0
Столбец «In_df2» имеет 1 в строке «0», потому что в df2 есть точное совпадение со строкой «0» в df1. В строке «1» есть 1, потому что в df2 есть совпадение 4/5 для строки «1» в df1. В строке «2» есть 0, потому что в df2 для строки «2» в df1 есть только совпадение 3/5.
Я написал код, чтобы сделать это вручную (см. Ниже), но я в некотором роде новичок в кодировании, и, как и следовало ожидать, это очень медленно. Я искал и не могу найти пакет, который, похоже, обрабатывает это частичное соответствие.
И последнее, вывод не обязательно должен быть столбцом, как я добавляю. Я действительно просто хочу идентифицировать все строки в df1, у которых нет партнера 4/5 или 5/5 в df2.
Спасибо за любые предложения!
Мой код:
def row_compare(row1, row2):
count = 0
if row1.ssn == row2.ssn:
count = 1
if row1.dob == row2.dob:
count = 1
if row1.sex == row2.sex:
count = 1
if row1.first_name == row2.first_name:
count = 1
if row1.last_name== row2.last_name:
count = 1
if count &&t;= 4:
out = 1
else:
out = 0
return out
за которым следует:
def row_to_df_compare(row1, df):
df['In_Other'] = df.apply(lambda row2 : row_compare(row1, row2), axis = 1)
if df.sum().In_Other &&t; 0:
out = 1
else:
out = 0
return out
и, наконец, с помощью:
df1['In_df2'] = df1.apply(lambda row : row_to_df_compare(row, df2), axis = 1)
Ответ №1:
мой коллега придумал этот ответ, который, похоже, работает в примере фреймов данных, которые я использую:
from itertools import combinations
df1['n_duplicates'] = 0
for columns in combinations(df2.columns, 4):
columns = list(columns)
df_concat = pd.concat([df1[columns], df2[columns]], i&nore_index = True, sort = False).reset_index(drop=True)
df1['n_duplicates'] = df_concat.duplicated(keep = False).astype(int).iloc[:df1.shape[0]]
df1_dedup = df1[df1['n_duplicates'] < 4]