Добро пожаловать на pandas
!Это довольно сложная проблема, потому что похоже, что вы хотите делать сравнения 1e5 * 1e5, что не будет быстрым, независимо от того, что мы делаем, поэтому давайте попробуем ограничить это настолько, насколько это возможно.Во-первых, сделайте все возможное, чтобы разумно ожидать, что соответствующие индексы будут близки.Во-вторых, вот код, который немного упростит ваше сопоставление.
Для двух серий x_row и y_row:
> x_row = pd.Series([1, 2, 0, 4])
> y_row = pd.Series([1, 2, 3, 4])
> ((x_row == y_row) | (x_row == 0)).all()
True
Эта последняя строка является побитовой или (|
)между двумя проверками: во-первых, если каждое значение соответствует соответствующему значению в другой серии (T, T, F, T
) или значение в x_row равно нулю (F F T F
).Битовый или из этих двух логических рядов равен T T T T
, поэтому в результате .all()
имеет значение True.
Вот пример использования этого в контексте, а также попытки ограничить числоиз сравнений, сделанных только из строки y_df
, когда совпадение было найдено.В идеальном случае это будет выполняться столько раз, сколько у вас будет строк.
x2y = []
unmatched_x = []
unmatched_y = df_y.index.tolist()
for x_idx, x_row in df_x:
match = False
for y_idx in unmatched_y:
if ((x_row == df_y.loc[y_idx]) | (x_row == 0)).all():
match = True
break
if match:
unmatched_y.remove(y_idx)
x2y.append(x_idx, y_idx)
else:
unmatched_x.append(x_idx)
Если вы считаете, что большинство из них совпадают, вы можете отсортировать те, которые выполняютrunning
matches = ((df_x == df_y) | (df_x == 0)).all(axis=1)
Это делает то же самое, но сразу для всего фрейма данных.Он вернет последовательность логических значений, соответствующую тому, соответствует ли каждая строка df_x
соответствующей строке df_y
.Затем вы можете сортировать те, которые не соответствуют.
df_x[matches]
будут только строки, которые соответствуют, или df_x[~matches]
будут те, которые не соответствуют.