这是我的previous post继续对公司名称的DataFrame进行非规范化的结果。
某些背景:
最初,我使用下表:
for data_batch, labels_batch in train_generator:
print("labels: ", labels_batch)
非规范化的目标是为所有没有丢失先前公司名称的实例添加新行,然后删除所有先前名称系列。
感谢 jezrael ,我能够通过以下代码实现这一目标:
import numpy as np
import pandas as pd
df = pd.DataFrame({'name' : ['Nitron', 'Pulset', 'Rotaxi'],
'postal_code' : [1410, 1020, 1310],
'previous_name1' : ['Rotory', np.NaN, 'Datec'],
'previous_name2' : [ np.NaN, 'Cmotor', np.NaN],
'previous_name3' : ['Datec', np.NaN, np.NaN],
'country' : ['BEL', 'ENG', 'JPN'],
'city' : ['Brussels', np.NaN, np.NaN]
})
print(df)
| name | postal_code | previous_name1 | previous_name2 | previous_name3 | country | city |
|--------|-------------|----------------|----------------|----------------|---------|----------|
| Nitron | 1410 | Rotory | NaN | Datec | BEL | Brussels |
| Pulset | 1020 | NaN | Cmotor | NaN | ENG | NaN |
| Rotaxi | 1310 | Cyclip | NaN | NaN | JPN | NaN |
新目标
我的新目标是添加一个附加标志/列,其值定义为
也就是说,新的DataFrame看起来应该像这样(列的顺序无关紧要):
df1 = (df.set_index(['postal_code','country','city'])
.stack()
.reset_index(level=3, drop=True)
.reset_index(name='name')
)
print (df1)
postal_code country city name
0 1410 BEL Brussels Nitron
1 1410 BEL Brussels Rotory
2 1410 BEL Brussels Datec
3 1020 ENG NaN Pulset
4 1020 ENG NaN Cmotor
5 1310 JPN NaN Rotaxi
6 1310 JPN NaN Datec
我尝试调整 jezrael 的代码,但没有成功。任何其他帮助将不胜感激。
答案 0 :(得分:2)
这是使用wide_to_long
df=df.rename({'name':'previous_name0'})
s=pd.wide_to_long(df,['previous'],i=['postal_code','country','city'],j='old_name_flag',sep='_',suffix='\w+').reset_index()
s=s[s.previous.notnull()]
s['old_name_flag']=s['old_name_flag'].ne('name0').astype(int)
s
Out[147]:
postal_code country city old_name_flag previous
0 1410 BEL Brussels 0 Nitron
1 1410 BEL Brussels 1 Rotory
3 1410 BEL Brussels 1 Datec
4 1020 ENG NaN 0 Pulset
6 1020 ENG NaN 1 Cmotor
8 1310 JPN NaN 0 Rotaxi
9 1310 JPN NaN 1 Datec
或者我们从您的df1开始
df1['old_name_flag']=df.groupby(['postal_code','country']).cumcount().ne(0).astype(int)
df1
Out[152]:
postal_code country city name old_name_flag
0 1410 BEL Brussels Nitron 0
1 1410 BEL Brussels Rotory 1
2 1410 BEL Brussels Datec 1
3 1020 ENG NaN Pulset 0
4 1020 ENG NaN Cmotor 1
5 1310 JPN NaN Rotaxi 0
6 1310 JPN NaN Datec 1
答案 1 :(得分:2)
重新索引时,信息已在数据框中:
df1 = (df.set_index(['postal_code','country','city'])
.stack()
# .reset_index(level=3, drop=True)
.reset_index(name='name')
)
df1['old_name_flag'] = df1['level_3'].ne('name')
df1.drop('level_3', axis=1, inplace=True)
print (df1)
输出:
postal_code country city name old_name_flag
0 1410 BEL Brussels Nitron False
1 1410 BEL Brussels Rotory True
2 1410 BEL Brussels Datec True
3 1020 ENG NaN Pulset False
4 1020 ENG NaN Cmotor True
5 1310 JPN NaN Rotaxi False
6 1310 JPN NaN Datec True
更新:您也可以按如下方式将命令与assign
链接在一起(尽管为清晰起见,我更喜欢使用单独的命令):
df1 = (df.set_index(['postal_code','country','city'])
.stack()
.reset_index(name='name')
.assign(old_name_flag=lambda x: x['level_3'].ne('name'))
.drop('level_3', axis=1)
)