如何";反规范化";数据帧/从多个二进制列中生成一列



我有一个数据框架,其中有许多二进制列,用于指示是否提到了特定的产品名称。我想创建一个单独的列,列出所有特定的产品名称,该行用1表示。

为了简单起见,假设这是我的数据帧:

df = pd.DataFrame({'Name': [1,0,0], 'Another Name': [0,1,1], 'Different Name':[0,0,1]})

我想创建这个专栏:

0 ['Name']
1 ['Another Name']
2 ['Another Name','Different Name']

我的思考过程是遍历每一行,如果任何名称都有1,则将其添加到列的列表中

namelist = list()
if df['Name']==1:
namelist.append("Name")
else if df['Another Name']==1:
namelist.append("Another Name")
else if df['Different Name']==1:
namelist.append("Different Name") 

但这不会保留特定于该行的列表。关于如何做到这一点的建议?

我的解决方案:我使用了G.Anderson解决方案中的逻辑,但我需要指定感兴趣的列,而不是数据帧中的所有列。我相信有一种比我最终做的更好的方法,但这就是我所做的:

df['Name']=df['Name'].replace({1:'Name',0:''})
df['Another Name']=df['Another Name'].replace({1:'Another Name',0:''})
df['Different Name']=df['Different Name'].replace({1:'Different Name',0:''})
df['Product Name']=df['Name'] + df['Another Name'] + df['Different Name']

这是我的镜头:

df = pd.DataFrame({'Name': (1,0,0), 'Another Name': [0,1,1], 'Different Name':[0,0,1]})
Name    Another Name    Different Name
0   1       0               0
1   0       1               0
2   0       1               1

将值替换为列名或''

for col in df.columns:
df[col]=df[col].replace({1:col,0:''})
Name    Another Name    Different Name
0   Name        
1           Another Name    
2           Another Name    Different Name

添加一列,该列是其他列值的列表

df['new_col']=df.iloc[:,:].apply(lambda x: [i for i in list(x) if i], axis=1)
Name    Another Name    Different Name  new_col
0   Name                                    [Name]
1           Another Name                    [Another Name]
2           Another Name    Different Name  [Another Name, Different Name]

删除其他列

df=df['new_col']
0                            [Name]
1                    [Another Name]
2    [Another Name, Different Name]
Name: new_col, dtype: object

(注意,我添加了一行,所以数据帧不方正,以帮助我确保正确性(

import pandas as pd 
df = pd.DataFrame({'Name': [1,0,0,0], 'Another Name': [0,1,1,0], 'Different Name':[0,0,1,1]})
df = pd.melt(df.mul(1+df.index,axis=0))
[(i, list(df[df.value==i].variable)) for i in set(df[df.value>0].value)]
[(1, ['Name']),
(2, ['Another Name']),
(3, ['Another Name', 'Different Name']),
(4, ['Different Name'])]

最新更新