让我们说像下面这样的列。
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。
有人有什么想法吗?
任何小小的想法都会帮助我!
谢谢!
答案 0 :(得分:4)
首先使用Series.str.split
和DataFrame.stack
创建Series
:
s = df['station'].str.split(expand=True).stack()
然后用boolean indexing
用Series.str.endswith
删除以min
结尾的值:
df1 = s[~s.str.endswith('min')].to_frame('data').rename_axis(('a','b'))
然后使用过滤和GroupBy.cumcount
为line
和station
行创建计数器:
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_index
用DataFrame.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