熊猫:根据部分匹配另一列名称的列值创建新列

时间:2019-05-23 10:36:21

标签: pandas apply

我正在尝试在Pandas中创建一个新列。我有一个现有的文本列,并且我希望这个新列包含另一个列中包含的值,其中行值与列名部分匹配。它类似于该线程,但就我而言,我只会部分匹配:

Python: pandas: match row value to column name/ key's value

我的桌子就像这样

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_rf4'中包含'UKA'

第二行与列名完全匹配,第三列是部分匹配。

有什么建议吗?

3 个答案:

答案 0 :(得分:2)

如果列之间总是匹配,并且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列和{ {3}}:

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 :(得分:1)

您可以使用列表理解

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

答案 2 :(得分:1)

我们仍然可以通过在此处清除列名来使用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