如何根据包含的文本值将熊猫数据框列拆分为多列

时间:2019-10-17 05:35:33

标签: python pandas

让我们说像下面这样的列。

df = pd.DataFrame(['A-line B-station 9-min C-station 3-min',
                   'D-line E-station 8-min F-line G-station 5-min',
                   'G-line H-station 1-min I-station 6-min J-station 8-min'],
                    columns=['station'])

A,B,C只是任意字符,并且像这样整行。

                                             station
0             A-line B-station 9-min C-station 3-min
1      D-line E-station 8-min F-line G-station 5-min
2  G-line H-station 1-min I-station 6-min J-stati...

如何创建如下所示的列?

   Line1     Station1-1   Station1-2 Station1-3   Line2    Station2-1
0  A-line    B-station    C-station    null       null     null
1  D-line    E-station    null         null       F-line   G-station
2  G-line    H-station    I-station    J-station  null     null

stationX-X表示站点(行号)-(站点的顺序)

Station1-1表示第一行(line1)的第一站

Station1-2表示第一行(line1)的第二站

Station2-1表示第二行(line2)的第一站

我试图用定界符分割;但是,这行不通,因为每一行都有不同数量的线路和桩号。

我可能需要根据包含的字符来拆分列。例如,我可以将第一个“ -line”存储到Line1,并将第一个“ -station”存储到station1-1。

有人有什么想法吗?

任何小小的想法都会帮助我!

谢谢!

1 个答案:

答案 0 :(得分:4)

首先使用Series.str.splitDataFrame.stack创建Series

s = df['station'].str.split(expand=True).stack()

然后用boolean indexingSeries.str.endswith删除以min结尾的值:

df1 = s[~s.str.endswith('min')].to_frame('data').rename_axis(('a','b'))

然后使用过滤和GroupBy.cumcountlinestation行创建计数器:

df1['Line'] = (df1[df1['data'].str.endswith('line')]
                         .groupby(level=0)
                         .cumcount()
                         .add(1)
                         .astype(str))
df1['Line'] = df1['Line'].ffill()

df1['station'] = (df1[df1['data'].str.endswith('station')]
                         .groupby(['a','Line'])
                         .cumcount()
                         .add(1)
                         .astype(str))

创建具有连接的系列,将df1['Line']的缺失值替换为Series.fillna

df1['station'] = (df1['Line'] + '-' + df1['station']).fillna(df1['Line'])

DataFrame.set_indexDataFrame.unstack重塑:

df1 = df1.set_index('station', append=True)['data'].reset_index(level=1, drop=True).unstack()

Rename列名-避免出现错误的排序顺序:

df1 = df1.rename(columns = lambda x: 'Station' + x if '-' in x else 'Line' + x)

删除列名称:

df1.columns.name = None
df1.index.name = None
print (df1)
    Line1 Station1-1 Station1-2 Station1-3   Line2 Station2-1
0  A-line  B-station  C-station        NaN     NaN        NaN
1  D-line  E-station        NaN        NaN  F-line  G-station
2  G-line  H-station  I-station  J-station     NaN        NaN