我有一个df
a name
1 a/b/c
2 w/x/y/z
3 q/w/e/r/t
我想在'/'上拆分名称列以获得此输出
id name main sub leaf
1 a/b/c a b c
2 w/x/y/z w x z
3 q/w/e/r/t q w t
即前两个斜杠分别添加为 main 和 sub , 在最后一次斜线之后,叶子应该用字填充
我尝试使用此功能,但结果不正确
df['name'].str.split('/', expand=True).rename(columns={0:'main',1:'sub',2:'leaf'})
有没有办法分配列
答案 0 :(得分:3)
s = df['name'].str.split('/')
df = df.assign(main=s.str[0], sub=s.str[1], leaf=s.str[-1])
print (df)
a name leaf main sub
0 1 a/b/c c a b
1 2 w/x/y/z z w x
2 3 q/w/e/r/t t q w
对于列的更改顺序:
s = df['name'].str.split('/')
df = df.assign(main=s.str[0], sub=s.str[1], leaf=s.str[-1])
df = df[df.columns[:-3].tolist() + ['main','sub','leaf']]
print (df)
a name main sub leaf
0 1 a/b/c a b c
1 2 w/x/y/z w x z
2 3 q/w/e/r/t q w t
或者:
s = df['name'].str.split('/')
df = (df.join(pd.DataFrame({'main':s.str[0], 'sub':s.str[1], 'leaf':s.str[-1]},
columns=['main','sub','leaf'])))
print (df)
a name main sub leaf
0 1 a/b/c a b c
1 2 w/x/y/z w x z
2 3 q/w/e/r/t q w t
答案 1 :(得分:2)
选项1
使用str.split
,但不扩展结果。您应该最终得到一列列表。接下来,使用df.assign
,指定列以返回新的DataFrame对象。
v = df['name'].str.split('/')
df.assign(
main=v.str[ 0],
sub=v.str[ 1],
leaf=v.str[-1]
)
name leaf main sub
a
1 a/b/c c a b
2 w/x/y/z z w x
3 q/w/e/r/t t q w
详细
这就是v
的样子:
a
1 [a, b, c]
2 [w, x, y, z]
3 [q, w, e, r, t]
Name: name, dtype: object
这实际上更容易处理,因为您可以更好地控制具有.str
访问者的元素。如果展开结果,则必须将不规则数据捕捉到表格格式以适合新的DataFrame对象,从而引入None
s。在那时,索引(找到第i个或第i个最后一个元素)变成了一件苦差事。
选项2
使用直接分配(维持秩序) -
df['main'] = v.str[ 0]
df['sub' ] = v.str[ 1]
df['leaf'] = v.str[-1]
df
name main sub leaf
a
1 a/b/c a b c
2 w/x/y/z w x z
3 q/w/e/r/t q w t
请注意,这会修改原始数据框,而不是返回一个新数据框,因此它更便宜。但是,如果您有大量列,则更难以处理。
您可以考虑使用此替代方案,该方案应推广到更多列:
for c, i in [('main', 0), ('sub', 1), ('leaf', -1)]:
df[c] = v[i]
df
name main sub leaf
a
1 a/b/c a b c
2 w/x/y/z w x z
3 q/w/e/r/t q w t
迭代元组列表。元组中的第一个元素是列名,第二个元素是从v
中选择结果的相应索引。无论你喜欢与否,你仍然必须分别分配每一个。使用循环可能是一种干净的方式。