Как заменить значения в фрейме данных pandas словарем? - PullRequest
0 голосов
/ 18 мая 2019

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

Name   User A1_Top  A2_Top
stefan1 721    A    C   
stefan2 721    A    G
stefan3 331    T    T   
stefan4 331    C    G
stefan5 331    A    A
stefan6 721    G    G   

И мне нужно изменить значения Top1 и Top2 по определенному ключу для каждой строки.

Например: if values in same rows will be = C & A, I will replace it to A & B, if row == TT will be BB и т. Д. (Введите, если / еще ниже).

Я получил ответ в другом посте, как это сделать по словарю, но я не могу справиться сэто двойное условие (если это будет одно условие, например, если A в первом ряду, замените на B, все будет в порядке).Поэтому я просто поместил его в цикл if / else, и он работает ... Я имею в виду, работал, он работал до тех пор, пока файлы не стали большими.Теперь это так медленно.300 МБ файл можно обрабатывать 30 минут на стандартном рабочем столе.

Вот так выглядит мой код:

def ATCG_to_AB(df):
x = 0
for i in range(lenFor):
    if df['A1_TOP'].iloc[i] == 'A' and df['A2_TOP'].iloc[i] =='C':
        df['A1_TOP'].iloc[i] = 'A'
        df['A2_TOP'].iloc[i] ='B'
    elif df['A1_TOP'].iloc[i] == 'A' and df['A2_TOP'].iloc[i] =='G':
        df['A1_TOP'].iloc[i] = 'A'
        df['A2_TOP'].iloc[i] ='B'
    elif df['A1_TOP'].iloc[i] == 'A' and df['A2_TOP'].iloc[i] =='T':
        df['A1_TOP'].iloc[i] = 'A'
        df['A2_TOP'].iloc[i] ='B'
    elif df['A1_TOP'].iloc[i] == 'C' and df['A2_TOP'].iloc[i] =='G':
        df['A1_TOP'].iloc[i] = 'A'
        df['A2_TOP'].iloc[i] ='B'
    elif df['A1_TOP'].iloc[i] == 'A' and df['A2_TOP'].iloc[i] =='A':
        df['A1_TOP'].iloc[i] = 'A'
        df['A2_TOP'].iloc[i] ='A'
    elif df['A1_TOP'].iloc[i] == 'C' and df['A2_TOP'].iloc[i] =='C':
        df['A1_TOP'].iloc[i] = 'B'
        df['A2_TOP'].iloc[i] ='B'
    elif df['A1_TOP'].iloc[i] == 'G' and df['A2_TOP'].iloc[i] =='G':
        df['A1_TOP'].iloc[i] = 'B'
        df['A2_TOP'].iloc[i] ='B'
    elif df['A1_TOP'].iloc[i] == 'T' and df['A2_TOP'].iloc[i] =='T':
        df['A1_TOP'].iloc[i] = 'B'
        df['A2_TOP'].iloc[i] ='B'
    else:
        print(x,". Something is wrong in line: ", i)
        x+=1

X - ошибки подсчета.И я знаю, что этот код ужасен, поэтому я попытался использовать метод словаря.Моя попытка:

L = [('A', 'C', 'A', 'B'),('A', 'G', 'A', 'B'),('A', 'T', 'A', 'B'),
 ('C', 'G', 'A', 'B'),('A', 'A', 'A', 'A'),('C', 'C', 'B', 'B'),
 ('G', 'G', 'B', 'B'),('T', 'T', 'B', 'B')]


for x in L:
    a.loc[(df[2] == x[0]) & (df[3] == x[1]), [2,3]] = [x[2], x[3]]

Но я получил плохой вывод.Изменяется только A1_top, и обычно это плохой символ.Может кто-нибудь помочь мне перевести мой уродливый код в словарь и объяснить это?И правильно ли я думаю, что это будет более быстрое решение?

Наверняка, ожидаемый результат (нет заголовков в выводе, ниже для ясности)

name   User A1_Top  A2_Top
    stefan1 721    A    B   
    stefan2 721    A    B   
    stefan3 331    B    B   
    stefan4 331    A    B
    stefan5 331    A    A
    stefan6 721    B    B   

1 Ответ

2 голосов
/ 18 мая 2019

Простой трюк, если не сказать лучший, но он работает: [Создать фиктивный столбец для сопоставления или df[col].apply]

df['combined'] = df['A1_Top']+"|"+df['A2_Top']

  A1_Top A2_Top combined
0      A      C      A|C
1      A      G      A|G
2      T      T      T|T
3      C      G      C|G
4      A      A      A|A
5      G      G      G|G

Создать словарь, сопоставляя все ваши требования: я даю 1 здесь

map_dict = {}
map_dict['A|C'] = 'B|C'
.
.
.

df['new_values'] = df['combined'].apply(lambda x:map_dict[x] if x in map_dict.keys() else x)

  A1_Top A2_Top combined new_values
0      A      C      A|C        B|C
1      A      G      A|G        A|G
2      T      T      T|T        T|T
3      C      G      C|G        C|G
4      A      A      A|A        A|A
5      G      G      G|G        G|G

df['new_a1_top'] = df['new_values'].apply(lambda x: x.split('|')[0])
df['new_a2_top'] = df['new_values'].apply(lambda x: x.split('|')[1])

  A1_Top A2_Top combined new_values new_a1_top new_a2_top
0      A      C      A|C        B|C          B          C
1      A      G      A|G        A|G          A          G
2      T      T      T|T        T|T          T          T
3      C      G      C|G        C|G          C          G
4      A      A      A|A        A|A          A          A
5      G      G      G|G        G|G          G          G
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...