В желаемом выводе используются разные значения и имя столбца для сравнения с вашим образцом конструктора данных. Я использую желаемый выходной кадр данных для тестирования.
Logi c:
Для каждого подсписка links
нам нужно найти индекс строки (я имею в виду индекс датафрейм, НЕ столбцы index
) первого перекрывающегося подсписка. Мы будем использовать эти индексы строк для нарезки на .loc
на counts95
, чтобы получить соответствующие значения столбца index
. Для достижения этой цели нам нужно выполнить несколько шагов:
- Сравнить каждый подсписок со всеми подсписками в
link
. Понимание списка быстро и эффективно для этой задачи. Нам нужно закодировать понимание списка, чтобы создать массив логических 2D-масок, в котором каждый подмассив содержит True
значений для перекрывающихся строк и False
для неперекрывающихся (посмотрите пошаговую инструкцию по этой 2D-маске и проверьте с помощью столбец links
вы увидите яснее) - Мы хотим сравнить сверху вниз с текущим подсписком. Т.е. стоя из текущего ряда, мы хотим только сравнить задом наперед. Поэтому нам нужно установить любое прямое сравнение на
False
. Это функциональность np.tril
- Внутри каждого подмассива этой 2D-маски позиция / индекс
True
- это индекс строки, на которую наложен текущий подсписок. Нам нужно найти эти позиции True
. Это функциональность np.argmax
. np.argmax
возвращает позицию / индекс первого элемента max массива. True
считается 1
, а False
- 0
. Следовательно, для любого подмассива, имеющего True
, он правильно возвращает индекс 1-й перекрытой строки. Однако для всего подмассива False
возвращается 0
. Мы будем обрабатывать все False
подмассив позже с where
- После
np.argmax
, 2D-маска уменьшается до 1D-маски. Каждый элемент этой 1D-маски представляет собой номер индекса строки перекрывающегося подсписка. Передав его в .loc
, вы получите соответствующие значения столбца index
. Однако результат также ошибочно включает строку, в которой подмассив 2D-маски содержит все False
. Мы хотим, чтобы эти строки превратились в NaN
. Это функциональность .where
Метод 1 :
Использование списка для построения логической 2D-маски m
между каждым списком links
и все списки в links
. Нам нужно только обратное сравнение, поэтому используйте np.tril
для cru sh верхний правый треугольник маски со всеми False
, что представляет прямое сравнение. Наконец, вызовите np.argmax
, чтобы получить позицию первого True
в каждом ряду m
и цепочку where
, чтобы превратить все False
строки m
в NaN
c95_list = counts95.links.tolist()
m = np.tril([[any(x in l2 for x in l1) for l2 in c95_list] for l1 in c95_list],-1)
counts95['linkoflist'] = (counts95.loc[np.argmax(m, axis=1), 'index']
.where(m.any(1)).to_numpy())
Out[351]:
index level0 links linkoflist
0 616351 25 [1, 2, 3, 4, 5] NaN
1 616352 30 [23, 45, 2] 616351.0
2 616353 35 [1, 19, 67] 616351.0
3 6457754 100 [14, 15, 16] NaN
4 6566666 200 [1, 14] 616351.0
5 6457754 556 [14, 1] 616351.0
Метод 2 :
Если ваш фрейм данных большой, сравнение каждого подсписка только с верхней частью links
делает его быстрее. Это вероятно в 2 раза быстрее, чем метод 1 на большом фрейме данных.
c95_list = counts95.links.tolist()
m = [[any(x in l2 for x in l1) for l2 in c95_list[:i]] for i,l1 in enumerate(c95_list)]
counts95['linkoflist'] = counts95.reindex([np.argmax(y) if any(y) else np.nan
for y in m])['index'].to_numpy()
Шаг за шагом (метод 1)
m = np.tril([[any(x in l2 for x in l1) for l2 in c95_list] for l1 in c95_list],-1)
Out[353]:
array([[False, False, False, False, False, False],
[ True, False, False, False, False, False],
[ True, False, False, False, False, False],
[False, False, False, False, False, False],
[ True, False, True, True, False, False],
[ True, False, True, True, True, False]])
argmax
возвращает оба положения первая True
и первая False
из всех - False
строк.
In [354]: np.argmax(m, axis=1)
Out[354]: array([0, 0, 0, 0, 0, 0], dtype=int64)
Нарезка с использованием результата argmax
counts95.loc[np.argmax(m, axis=1), 'index']
Out[355]:
0 616351
0 616351
0 616351
0 616351
0 616351
0 616351
Name: index, dtype: int64
Цепочка where
для поворота строк соответствует всем False
от m
до NaN
counts95.loc[np.argmax(m, axis=1), 'index'].where(m.any(1))
Out[356]:
0 NaN
0 616351.0
0 616351.0
0 NaN
0 616351.0
0 616351.0
Name: index, dtype: float64
Наконец, индекс вывода отличается от индекса counts95
, поэтому просто вызовите to_numpy
, чтобы получить ndarray присвоить столбцу linkoflist
из counts95
.