Условная замена чисел в pandas df

#regex #python-3.x #pandas

#регулярное выражение #python-3.x #pandas

Вопрос:

Учитывая следующие pandas df:

 import pandas as pd


df = pd.DataFrame({'1676' : ['R','NR','R','NR'],
               '1677' : ["NR", "NR" ,"NR", "NR"],
               '1710' : ["R", "R" , "NR", "NR"],
               '1536' : ["NR", "R", "NR", "R"]})

df
    1676    1677    1710    1536
0   R       NR      R       NR
1   NR      NR      R       R
2   R       NR      NR      NR
3   NR      NR      NR      R
  

и это более длинный pandas df2:

 df2 = pd.DataFrame({'1' : ['1710','1676','2651','1676'],
               '2' : ["2654", "2824" ,"1676", "1677"],
               '3' : ["1676", "3079" , "1677", "2085"],
               '4' : ["1536", "1677", "1409", "1536"],
                  '5' : ["510", "1710" , "1664", "1710"],
                  '6' : ["2590", "3090" , "2252", "2916"],
                  '7' : ["2777", "1536" , "1710", "3140"],
                  '8' : ["1677", "1709" , "1536", "1963"]})

    1       2       3       4       5       6       7       8
0   1710    2654    1676    1536    510     2590    2777    1677
1   1676    2824    3079    1677    1710    3090    1536    1709
2   2651    1676    1677    1409    1664    2252    1710    1536
3   1676    1677    2085    1536    1710    2916    3140    1963
  

Мне интересно, возможно ли следующее по строкам (здесь для первой строки):

  • для каждого значения в df.loc[0,] = "R"
  • возьмите соответствующее имя столбца (номер)
  • поиск числа в df2.loc[0,]
  • замените число в df2.loc[0,] на "R"

Так что я получаю это:

     1       2       3       4       5       6       7       8
0   R       2654    R       1536    510     2590    2777    1677
1   1676    2824    3079    1677    R       3090    R       1709
2   2651    R       1677    1409    1664    2252    1710    1536
3   1676    1677    2085    R       1710    2916    3140    1963
  

Редактировать:

Это не работает для моих конкретных df. Есть какие-либо предположения, что вызывает эту проблему? Я уже пробовал сбросить индексы.

Это df из поста выше:

введите описание изображения здесь

Это df2 из поста выше:

введите описание изображения здесь

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

1. Почему некоторые значения заменяются, а некоторые нет? Они должны быть в той же строке, что и в первом фрейме данных?

2. да, строки очень важны в этом случае

Ответ №1:

Используйте np.where и replace :

 import numpy as np
r, c = np.where(df=='R')

df2.apply(lambda x: x.replace(df.columns[c[(r == x.name)]], 'R'), axis=1)
  

Вывод:

       1     2     3     4     5     6     7     8
0     R  2654     R  1536   510  2590  2777  1677
1  1676  2824  3079  1677     R  3090     R  1709
2  2651     R  1677  1409  1664  2252  1710  1536
3  1676  1677  2085     R  1710  2916  3140  1963
  

Подробные сведения:

  • Сначала найдите строку и столбцы в df, где они равны ‘R’
  • Используйте apply с axis= 1, чтобы перейти строка за строкой, x.name определите, индекс какой строки ищет позицию в C, где это равно индексу строки, и получите заголовок столбца из df в этой позиции.
  • Используйте replace для замены всех значений заголовка столбца в df в этой строке.

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

1. @Scott Boston: Большое спасибо! Это работает нормально! К сожалению, это не работает для моего конкретного кода, который я не публиковал здесь для целей воспроизведения. Я обновил сообщение двумя фотографиями моих df.

2. Вы повторно присваиваете результаты df?

Ответ №2:

Здесь вы идете update с stack и lookup

 s=df2.stack()
s=s[s.isin(df.columns)]
df2.update(pd.Series(df.mask(df=='NR').lookup(s.index.get_level_values(0),s),s.index).unstack())
df2
Out[103]: 
      1     2     3     4     5     6     7     8
0     R  2654     R  1536   510  2590  2777  1677
1  1676  2824  3079  1677     R  3090     R  1709
2  2651     R  1677  1409  1664  2252  1710  1536
3  1676  1677  2085     R  1710  2916  3140  1963
  

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

1. Я не знаю, почему у меня такая мысленная блокировка при «поиске», я никогда не вспоминаю этот метод при решении проблем. 1

2. Никогда не используйте .lookup ни то, ни другое, поскольку документации об этом почти нет. Было бы полезно знать, в каких ситуациях использовать. @Wen-Ben, может быть, вопросы и ответы по этому поводу?

3. @ScottBoston ага 🙂 , я думаю, что поиск не так важен, я полагаю, вы знаете, что десятки способов могут сделать то же самое 🙂

4. @Erfan точно так же, как проверка индекса и столбцов 🙂

5. @Wen-Ben: Большое спасибо! Это работает нормально! К сожалению, это не работает для моего конкретного кода, который я не публиковал здесь для целей воспроизведения. Я обновил сообщение двумя изображениями моих конкретных df.