Как сравнить, совпадают ли какие-либо элементы из списка в соседних строках фрейма данных

#python #pandas #dataframe #data-science

Вопрос:

У меня есть фрейм данных pandas, который содержит список в столбце DIAG_CD (<класс ‘список’>):

Вот пример, но набор данных потенциально может содержать до 100 000 строк.

             DIAG_CODE
0          [  "M9901",   "M9902",   "M9903",   "M5412"]

1          [  "M9901"]

2          [  "M9901",   "M9902",   "M9903",   "M5412"]

3          [  "M9901",   "M9902",   "M9903",   "M542"]

...

20    [  "M542",   "M9902",   "M9903",   "M25519",  ...

21    [  "M542",   "M9902",   "M9903",   "M25519",  ...
 

Моя цель-посмотреть, совпадают ли какие-либо элементы в списке на двух соседних строках. Например, есть ли в списке из строки 0 какие-либо элементы в списке в строке 1, и ответ «да». Аналогично, строка 1 соответствует строке 2.

Я пробовал разные вещи, но не могу заставить это работать.

Я попробовал это сделать, но это привело к ошибке — атрибутивная ошибка: у объекта «список» нет атрибута «разделение»:
zipped = zip(df1['DIAG_CD'], df1['DIAG_CD'].shift(1))
df1['diagCodeMatch'] = [int(bool(set(a.split(',')) amp; set(b.split(',')))) for a, b in
zipped]
это также приводит к ошибке — df1['DIAG_CD']amp; df1['DIAG_CD'].shift(1)

Ошибка типа: неподдерживаемые типы операндов для amp;: «список» и «список»

Я довольно новичок в python и панд, так что любая помощь будет очень признательна.

Это то, что у меня сейчас есть:

 df = pd.read_parquet("samplefile.parquet", engine='pyarrow')
print(df.head(20))
#remove newline characters
df.replace(to_replace=[r"\t|\n|\r", "t|n|r"], value=["",""], regex=True, inplace=True)
df['intersection'] = [list(set(a).intersection(set(b))) for a, b in zip(df['DIAG_CD'], df['DIAG_CD'].shift(1))]
 

Комментарии:

1. Пожалуйста, опубликуйте чистый воспроизводимый образец.

Ответ №1:

Поскольку кажется, что вы сохраняете списки в каждой строке, есть несколько способов сделать это, но один из эффективных способов-превратить списки в наборы и использовать not set(a).isdisjoint(b) их для проверки наличия в них общих элементов или нет. Таким образом, вы могли бы сделать следующее:

 for i in range(df.DIAG_CD.shape[0]-1):
    mutual_elements_exist = not set([df.DIAG_CD.iloc[i]]).isdisjoint([df.DIAG_CD.iloc[i 1]])
    print(f'Shared elements between row_{i}_and_row_{i 1} is {mutual_elements_exist}')

 

Это вернет True значение, если какие-либо значения являются общими и False если ни одно из них не является общим. Я добавил функцию печати, потому что неясно, чего именно вы хотели бы достичь с помощью этого. Существует также довольно много различных способов группировки результатов, но из-за отсутствия информации я оставил все как есть.

РЕДАКТИРОВАТЬ: Я исправил проблему и изменил ее, чтобы вы могли запустить ее напрямую.

Комментарии:

1. Во фрейме данных есть много столбцов (имя = df), включая даты начала и окончания. Я пытаюсь принять решение, основанное на том факте, что если дата начала изменилась, но в столбце DIAG_CD был соответствующий элемент из списка предыдущей строки (любой элемент), я выполняю действие. У меня есть фрейм данных, сгруппированный и отсортированный по нескольким столбцам. Я попробовал ваш код, но получил следующую ошибку: Файл "<ipython-input-223-44c6301066f3>", строка 4 i в диапазоне(df1.shape[0]-1): ^ Ошибка синтаксиса: недопустимый синтаксис

2. Является ли серия "df1" серией? Каков результат запуска df1.shape? Смысл в том, чтобы просто найти диапазон строк.

3. В нем отсутствовало ключевое слово для, добавление его исправило это. Да, это серия. Когда я создаю фигуру во фрейме данных, я получаю 10 000, что соответствует количеству строк во фрейме данных. Большое вам спасибо за вашу помощь.

4. Это верно для каждой отдельной строки, однако, глядя на данные, это не так.

5. Это странно, так как это не относится к фрейму данных, который я придумал и попробовал. Я проверю это для тебя позже.