Панды слияния обрабатывают дубликаты в выводе соединения - PullRequest
0 голосов
/ 11 ноября 2018

Есть ли хороший способ привести только одну строку, желательно случайную, в соответствии «один ко многим» во время левого соединения в Пандах?

например,

left = [[1,1,1], [2,2,2],[3,3,3], [9,9,9], [1,3,2]]
right = [[1,2,2],[1,2,3],[3,2,2], [3,2,9], [3,2,2]]
left = np.asarray(left)
right = np.asarray(right)
left = pd.DataFrame(left)
right = pd.DataFrame(right)
joined_left = left.merge(right, how="left", left_on=[0], right_on=[0])

Так вот что мы получаем

   0  1  2
0  1  1  1
1  2  2  2
2  3  3  3
3  9  9  9
4  1  3  2

   0  1  2
0  1  2  2
1  1  2  3
2  3  2  2
3  3  2  9
4  3  2  2

   0  1_x  2_x  1_y  2_y
0  1    1    1  2.0  2.0
1  1    1    1  2.0  3.0
2  2    2    2  NaN  NaN
3  3    3    3  2.0  2.0
4  3    3    3  2.0  9.0
5  3    3    3  2.0  2.0
6  9    9    9  NaN  NaN
7  1    3    2  2.0  2.0
8  1    3    2  2.0  3.0

Так что теперь я хочу, чтобы выходные данные были того же размера, что и мой левый кадр данных, и когда в правом кадре данных имеется более одного совпадения, я хочу вывести только один случайный столбец.

Есть ли хороший способ сделать это, используя хитрые уловки панд?

спасибо!

1 Ответ

0 голосов
/ 11 ноября 2018

Вы можете перемешать right и drop_duplicates(...[, keep='first']) перед объединением.

right2 = right.sample(frac=1).drop_duplicates(subset=[0])
left.merge(right2, how='left', left_on=[0], right_on=[0])

   0  1_x  2_x  1_y  2_y
0  1    1    1  2.0  2.0
1  2    2    2  NaN  NaN
2  3    3    3  2.0  2.0
3  9    9    9  NaN  NaN
4  1    3    2  2.0  2.0

Сначала мы перетасовываем right, а затем отбрасываем каждый дубликат, кроме первой строки (с учетом только столбца № 0), что аналогично случайному выбору строки.

...