Сравните два разных фрейма данных на основе условий нескольких строк - PullRequest
2 голосов
/ 13 июля 2020

У меня есть два фрейма данных, содержащие разную информацию об одних и тех же пациентах. Мне нужно использовать фрейм данных 1 для фильтрации фрейма данных 2, чтобы фрейм данных 2 сохранял только целочисленные значения строки пациента, если в df_1 есть целочисленное значение для тех же chromosome, strand, elementloc и patient. Если в df_1 есть значение NaN, я хотел бы поместить NaN в df_2 в том же месте. Для значений NaN уже в df_2 я хотел бы оставить их как NaN.

Так, с df_1 и df_2, например:

df_1 = pd.DataFrame({'chromosome': [1, 1, 5, 4],
                     'strand': ['-', '-', '+', '-'],
                     'elementloc': [4991, 8870, 2703, 9674],
                     'Patient1_Reads': ['NaN', 25, 50, 'NaN'],
                     'Patient2_Reads': [35, 200, 'NaN', 500]})

print(df_1)                                                                    
   chromosome strand  elementloc Patient1_Reads Patient2_Reads
0           1      -        4991            NaN             35
1           1      -        8870             25            200
2           5      +        2703             50            NaN
3           4      -        9674            NaN            500


df_2 = pd.DataFrame({'chromosome': [1, 1, 5, 4],
                     'strand': ['-', '-', '+', '-'],
                     'elementloc': [4991, 8870, 2703, 9674],
                     'Patient1_PSI': [0.76, 0.35, 0.04, 'NaN'],
                     'Patient2_PSI': [0.89, 0.15, 0.47, 0.32]})
print(df_2)                                                                      
   chromosome strand  elementloc   Patient1_PSI    Patient2_PSI
0           1      -        4991           0.76            0.89
1           1      -        8870           0.35            0.15
2           5      +        2703           0.04            0.47
3           4      -        9674            NaN            0.32

Я бы хотел, чтобы новый df_2 выглядел так:

   chromosome strand  elementloc  Patient1_PSI  Patient2_PSI
0           1      -        4991           NaN          0.89
1           1      -        8870          0.35          0.15
2           5      +        2703          0.04           NaN
3           4      -        9674           NaN          0.32
    

1 Ответ

2 голосов
/ 13 июля 2020

Используйте:

df3 = df1.merge(df2, on=['chromosome', 'strand', 'elementloc'])

r_cols = df3.columns[df3.columns.str.endswith('_Reads')]
p_cols = r_cols.str.strip('Reads') + 'PSI'

df3[p_cols] = df3[p_cols].mask(df3[r_cols].isna().to_numpy())
df3 = df3.drop(r_cols, 1)

Подробности:

ШАГ A: Используйте DataFrame.merge для создания объединенный фрейм данных df3, полученный путем объединения фреймов данных df1 и df2 на ['chromosome', 'strand', 'elementloc'].

# print(df3)
   chromosome strand  elementloc  Patient1_Reads  Patient2_Reads  Patient1_PSI  Patient2_PSI
0           1      -        4991             NaN            35.0          0.76          0.89
1           1      -        8870            25.0           200.0          0.35          0.15
2           5      +        2703            50.0             NaN          0.04          0.47
3           4      -        9674             NaN           500.0           NaN          0.32

ШАГ B: Используйте .str.endswith, чтобы получить столбцы в df3, который заканчивается на _Reads, мы называем эти столбцы r_cols, затем используем эти _Reads столбцы для получения соответствующих _PSI столбцов, которые мы называем этими столбцами p_cols.

# print(r_cols)
Index(['Patient1_Reads', 'Patient2_Reads'], dtype='object')

# print(p_cols)
Index(['Patient1_PSI', 'Patient2_PSI'], dtype='object')

STEP C: используйте DataFrame.isna в столбцах _Reads, чтобы получить логическую маску , затем используйте эту маску вместе с DataFrame.mask, чтобы заполнить соответствующие NaN значения в _PSI столбцах. Наконец, используйте DataFrame.drop, чтобы удалить столбец _Reads из объединенного кадра данных df3, чтобы получить желаемый результат:

# print(df3)
   chromosome strand  elementloc  Patient1_PSI  Patient2_PSI
0           1      -        4991           NaN          0.89
1           1      -        8870          0.35          0.15
2           5      +        2703          0.04           NaN
3           4      -        9674           NaN          0.32
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...