Pandas: одновременное назначение нескольких * новых * столбцов

У меня есть DataFrame с столбцом, содержащим метки для каждой строки (в дополнение к некоторым релевантным данным для каждой строки). У меня есть словарь с ключами, равными возможным ярлыкам и значениям, равным 2-мя символами информации, относящейся к этой метке. Я хотел бы привязать две новые колонки к моему кадру, по одной для каждой части 2-х кортежей, соответствующей метке для каждой строки.

Вот настройка:

import pandas as pd import numpy as np np.random.seed(1) n = 10 labels = list('abcdef') colors = ['red', 'green', 'blue'] sizes = ['small', 'medium', 'large'] labeldict = {c: (np.random.choice(colors), np.random.choice(sizes)) for c in labels} df = pd.DataFrame({'label': np.random.choice(labels, n), 'somedata': np.random.randn(n)}) 

Я могу получить то, что хочу, запустив:

 df['color'], df['size'] = zip(*df['label'].map(labeldict)) print df label somedata color size 0 b 0.196643 red medium 1 c -1.545214 green small 2 a -0.088104 green small 3 c 0.852239 green small 4 b 0.677234 red medium 5 c -0.106878 green small 6 a 0.725274 green small 7 d 0.934889 red medium 8 a 1.118297 green small 9 c 0.055613 green small 

Но как я могу это сделать, если я не хочу вручную вводить два столбца в левой части задания? Т.е. как я могу создать несколько новых столбцов на лету. Например, если бы у меня было 10 кортежей в labeldict вместо 2-х кортежей, это было бы настоящей болью, как в настоящее время написано. Вот пара вещей, которые не работают:

 # set up attrlist for later use attrlist = ['color', 'size'] # non-working idea 1) df[attrlist] = zip(*df['label'].map(labeldict)) # non-working idea 2) df.loc[:, attrlist] = zip(*df['label'].map(labeldict)) 

Это действительно работает, но похоже на взлом:

 for a in attrlist: df[a] = 0 df[attrlist] = zip(*df['label'].map(labeldict)) 

Лучшие решения?

2 Solutions collect form web for “Pandas: одновременное назначение нескольких * новых * столбцов”

Вместо этого вы можете использовать слияние:

 >>> ld = pd.DataFrame(labeldict).T >>> ld.columns = ['color', 'size'] >>> ld.index.name = 'label' >>> df.merge(ld.reset_index(), on='label') label somedata color size 0 b 1.462108 red medium 1 c -2.060141 green small 2 c 1.133769 green small 3 c 0.042214 green small 4 e -0.322417 red medium 5 e -1.099891 red medium 6 e -0.877858 red medium 7 e 0.582815 red medium 8 f -0.384054 red large 9 d -0.172428 red medium 

Вместо того, чтобы делать то, что вы делаете с labeldict, вы можете сделать эту информацию в DataFrame, а затем присоединиться к ней с оригинальной:

 >>> labeldf = pandas.DataFrame([(np.random.choice(colors), np.random.choice(sizes)) for c in labels], columns=['color', 'size'], index=labels) >>> df.join(labeldf, on='label') label somedata color size 0 a -1.709973 red medium 1 b 0.099109 blue medium 2 a -0.427323 red medium 3 b 0.474995 blue medium 4 b -2.819208 blue medium 5 d -0.998888 red small 6 b 0.713357 blue medium 7 d 0.331989 red small 8 e -0.906240 green large 9 c -0.501916 blue large 
Python - лучший язык программирования в мире.