需求:将
Brands_rank
列中的不同品牌名,单独列出来
观察数据:不同的品牌名,由横杆(-)隔开,第3行只有1个横杆(-)
为实现需求,可以将
Brands_rank
列拆为3列,或者将3行
Brands_rank
数据拆为8行。
# -*- coding:utf-8 -*-
import pandas as pd
import numpy as np
Type Brands_rank
0 Computer Mac-Dell-Lenovo
1 Phone Mac-XiaoMi-HuaWei
2 Pad Mac-HuaWei
一列拆多列
获取Type
列
df_column = df.Type.to_frame()
print(df_column)
0 Computer
1 Phone
2 Pad
基于Brands_rank
列构造多列
方法一:当截取的内容长度和位置固定时,可直接使用字符串切片,本例中,以截取Brands_rank
的Mac
为例
df_column['Brands-First'] = df.Brands_rank.astype('str').str[0:3]
print(df_column)
Type Brands-First
0 Computer Mac
1 Phone Mac
2 Pad Mac
方法二:当截取的内容长度不固定时,如Brands_rank
中横杆(-)的中间部分,字符串长度不一致,使用字符串分割函数split()
df_column['Brands-Second'] = df.Brands_rank.apply(lambda x: x.split('-')[1])
print(df_column)
Type Brands-First Brands-Second
0 Computer Mac Dell
1 Phone Mac XiaoMi
2 Pad Mac HuaWei
方法三:当分隔符个数不同时,需要对分隔符的个数做判断,本例中是横杆(-),其个数不够2个时返回None
。一列拆为3列的结果如下:
df_column['Brands-Third'] = df.Brands_rank.apply(lambda x: x.split('-')[2] if x.count('-') >= 2 else np.nan)
print(df_column)
Type Brands-First Brands-Second Brands-Third
0 Computer Mac Dell Lenovo
1 Phone Mac XiaoMi HuaWei
2 Pad Mac HuaWei NaN
一行拆多行
方法一:基于一列拆多列的结果,多次选取列再拼接。该方法容易理解,前提是需要先实现一列拆多列、代码冗余不优雅
df_index_1 = df_column[['Type', 'Brands-First']].rename(columns={'Brands-First':'Brands'})
df_index_2 = df_column[['Type', 'Brands-Second']].rename(columns={'Brands-Second':'Brands'})
df_index_3 = df_column[['Type', 'Brands-Third']].rename(columns={'Brands-Third':'Brands'})
df_index = pd.concat([df_index_1, df_index_2, df_index_3]).dropna().sort_index()
print(df_index)
Type Brands
0 Computer Mac
0 Computer Dell
0 Computer Lenovo
1 Phone Mac
1 Phone XiaoMi
1 Phone HuaWei
2 Pad Mac
2 Pad HuaWei
方法二、直接对Brands_rank
列进行分割(split)
,再堆叠(stack)
处理,堆叠后会出现多级索引,删除多级索引后再拼接。3行拆分为8行的结果如下:
df_index = df.Brands_rank.str.split('-', expand=True).stack().to_frame()
df_index = df_index.reset_index(level=1, drop=True).rename(columns={0:'Brands'})
df[['Type']].join(df_index)
Type Brands
0 Computer Mac
0 Computer Dell
0 Computer Lenovo
1 Phone Mac