Цикл for по столбцам датафрейма
Есть датафрейм:
a = pd.DataFrame({'ab':['abc','bde'],'ac':['abcc','bdec'],'Sum':[1,2]})`
список столбцов:
lst = ['ab','ac']
Нужно применить к этим столбцам функцию в цикле for:
for i in lst:
a.i = a.i.str.replace('b', '89')
но выдаёт ошибку. Пробовал варианты:
for i in lst:
a.globals()[i] = a.globals()[i].str.replace('b', '89')
и
for i in lst:
eval('a.' + globals()[i]) = eval('a.' + globals()[i]).str.replace('b', '89')
но тоже ошибка. Как правильно написать цикл for по списку названий колонок датафрейма?
Ответы (2 шт):
можно этот список использовать для индексирования по столбцам
ab ac Sum
0 abc abcc 1
1 bde bdec 2
a[lst] = a[lst].apply(lambda x: x.str.replace('b', '89'))
ab ac Sum
0 a89c a89cc 1
1 89de 89dec 2
можно сделать проще
a[lst] = a[lst].replace('b', '89', regex=True)
но при рельных данных надо учитывать, что выражения для замены будут интерпретироваться как регулярные выражения, а с regex=False, замена будет происходить только в случае полного совпадения содержимого ячейки с образцом
for i in lst:
a.i = a.i.str.replace('b', '89')
AttributeError: 'DataFrame' object has no attribute 'i'
Нужно помнить, что обращение к колонкам датафрейма как к атрибутам через точку - это не стабильная фича, а просто приятное дополнение к основным, более правильным способам, имеющая много ограничений. Кроме того, тут вы фактически обращаетесь к столбцу с именем i, а не к тому столбцу, имя которого находится в переменной i.
Правильный (но устаревший) метод - это обращение через индексацию (квадратные скобки):
for i in lst:
a[i] = a[i].str.replace('b', '89')
Но самый правильный и современный способ - это использовать метод .loc, с указанием строк и столбцов, к которым вы обращаетесь (в данном случае это все строки, для этого используется срез :):
for i in lst:
a.loc[:,i] = a[:,i].str.replace('b', '89')
Но вообще работать с датафреймами в цикле не очень хорошо, лучше использовать другие методы, описанные, например, в другом ответе на этот вопрос.