将DataFrame字符串列拆分为N个拆分

时间:2018-01-22 13:02:32

标签: python string pandas dataframe split

我有一个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'})

有没有办法分配列

2 个答案:

答案 0 :(得分:3)

split使用assign

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中选择结果的相应索引。无论你喜欢与否,你仍然必须分别分配每一个。使用循环可能是一种干净的方式。