Панды: создание нового столбца на основе значения столбца, частично совпадающего с именем другого столбца - PullRequest
2 голосов
/ 23 мая 2019

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

Python: pandas: сопоставить значение строки с именем столбца / значением ключа

Моя таблица будет выглядеть в качестве примера

Field   UKA_rf4 UKB UKDdsdf 
UKA     1       4   54
UKB     2       5   7787    
UKD     97      54  765656  

И что бы я хотел, чтобы это выглядело так:

Field   UKA_rf4 UKB UKDdsdf      Value
UKA     1       4   54           1
UKB     2       5   7787         5
UKD     97      54  765656       765656   

Первая строка приводит к 1, потому что «UKA» содержится в имени столбца «UKA_rf4»

Вторая строка точно соответствует имени столбца, а третий столбец - частичное совпадение.

Есть предложения?

Ответы [ 3 ]

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

Если всегда есть совпадение между столбцами и каждым значением Field, используйте DataFrame.lookup:

s = df['Field']
a = df.columns.str.extract('(' + '|'.join(s) + ')', expand=False)
df['Value'] = df.set_axis(a, axis=1,inplace=False).lookup(df.index, s)
print (df)
  Field  UKA_rf4  UKB  UKDdsdf   Value
0   UKA        1    4       54       1
1   UKB        2    5     7787       5
2   UKD       97   54   765656  765656

Аналогичное решение:

df = df.set_index('Field')
a = df.columns.str.extract('(' + '|'.join(s) + ')', expand=False)
df['Value'] = df.set_axis(a, axis=1,inplace=False).lookup(df.index, df.index)

Но проблема с lookup в том случае, если некоторые значения отсутствуют, поэтому здесь есть альтернатива с DataFrame.melt для изменения формы, извлеките столбцы с помощью Series.str.extract со всеми значениями Field столбец и Series.map:

df1 = df.melt('Field', var_name='var')
df1['cols'] = df1['var'].str.extract('(' + '|'.join(df['Field']) + ')', expand=False)
s = df1[df1['Field'] == df1['cols']].drop_duplicates('Field').set_index('Field')['value']

df['Value'] = df['Field'].map(s)
print (df)
  Field  UKA_rf4  UKB  UKdsdf  Value
0   UKA        1    4      54    1.0
1  UKB1        2    5    7787    NaN
2   UKD       97   54  765656    NaN
1 голос
/ 23 мая 2019

Мы все еще можем использовать lookup, очистив названия столбцов здесь:

df2 = df.copy()
df2.columns = ['Field'] + [col[:3] for col in df2.iloc[:, 1:].columns]
df['Value'] = df2.lookup(df2.index, df2['Field'])

  Field  UKA_rf4  UKB  UKDdsdf   Value
0   UKA        1    4       54       1
1   UKB        2    5     7787       5
2   UKD       97   54   765656  765656
1 голос
/ 23 мая 2019

Вы можете использовать понимание списка

df = pd.DataFrame({'Fields':['UKA','UKB','UKD'],'UKA_rf4':[1,2,97],'UKB':[4,5,54],'UKDdsdf':[54,7787,765656]})

df = df.set_index('Fields')
df['Values'] = [df[j][index] for index,i in enumerate(df.index) for j in df.columns if i in j]

print(df)

        UKA_rf4  UKB  UKDdsdf  Values
Fields                               
UKA           1    4       54       1
UKB           2    5     7787       5
UKD          97   54   765656  765656
...