Эффективное создание дополнительных столбцов в панде DataFrame с помощью.map()

Я анализирую набор данных, который по форме похож на следующий пример. У меня есть два разных типа данных (abc data и xyz data):

   abc1  abc2  abc3  xyz1  xyz2  xyz3
0     1     2     2     2     1     2
1     2     1     1     2     1     1
2     2     2     1     2     2     2
3     1     2     1     1     1     1
4     1     1     2     1     2     1

Я хочу создать функцию, которая добавляет столбец категоризации для каждого столбца abc, который существует в кадре данных. Используя списки имен столбцов и словарь сопоставления категорий, я смог получить желаемый результат.

abc_columns = ['abc1', 'abc2', 'abc3']
xyz_columns = ['xyz1', 'xyz2', 'xyz3']
abc_category_columns = ['abc1_category', 'abc2_category', 'abc3_category']
categories = {1: 'Good', 2: 'Bad', 3: 'Ugly'}

for i in range(len(abc_category_columns)):
    df3[abc_category_columns[i]] = df3[abc_columns[i]].map(categories)

print df3

Конечный результат:

   abc1  abc2  abc3  xyz1  xyz2  xyz3 abc1_category abc2_category abc3_category
0     1     2     2     2     1     2          Good           Bad           Bad
1     2     1     1     2     1     1           Bad          Good          Good
2     2     2     1     2     2     2           Bad           Bad          Good
3     1     2     1     1     1     1          Good           Bad          Good
4     1     1     2     1     2     1          Good          Good           Bad

В то время как for цикл в конце работает нормально, я чувствую, что я должен использовать Python lambda функция, но не могу понять это.

Есть ли более эффективный способ отобразить динамическое число столбцов типа abc?

1 ответ

Решение

Ты можешь использовать applymap со словарем get метод:

In [11]: df[abc_columns].applymap(categories.get)
Out[11]:
   abc1  abc2  abc3
0  Good   Bad   Bad
1   Bad  Good  Good
2   Bad   Bad  Good
3  Good   Bad  Good
4  Good  Good   Bad

И поместите это в указанные столбцы:

In [12]: abc_categories = map(lambda x: x + '_category', abc_columns)

In [13]: abc_categories
Out[13]: ['abc1_category', 'abc2_category', 'abc3_category']

In [14]: df[abc_categories] = df[abc_columns].applymap(categories.get)

Примечание: вы можете построить abc_columns относительно эффективно использовать понимание списка:

abc_columns = [col for col in df.columns if str(col).startswith('abc')]
Другие вопросы по тегам