我有以下数据框架,我想将Col2拆分为多列:
输入数据框:
>>> mydf= pd.DataFrame({'Col1':['AA','AB','AAC'], 'Col2':['AN||Ind(0.9)','LN||RED(8.9)','RN||RED(9.8)'], 'Col3':['log1','log2','log3']})
>>> mydf
Col1 Col2 Col3
0 AA AN||Ind(0.9) log1
1 AB LN||RED(8.9) log2
2 AAC RN||RED(9.8) log3
所需的数据框:
Col1 Col2 Col3 Col4 Col5
0 AA AN log1 Ind 0.9
1 AB LN log2 RED 8.9
2 AAC RN log3 RED 9.8
我从申请开始,但以下将采取好几步。任何快捷方式?
mydf['Col4']=mydf['Col2'].apply(lambda x: str(x).split('||')[0])
也很少感到困惑,为什么以下会引发估值:
mydf['Col2'].str.split('||', expand=True)
ValueError: split() requires a non-empty pattern match.
您可以用str.extract
和assign
regex = '(?P<Col2>.*)|{2,}(?P<Col4>.*)((?P<Col5>.*))'
mydf.assign(**mydf.Col2.str.extract(regex, expand=True).to_dict('list'))
Col1 Col2 Col3 Col4 Col5
0 AA AN log1 Ind 0.9
1 AB LN log2 RED 8.9
2 AAC RN log3 RED 9.8
或与combine_first
regex = '(?P<Col2>.*)|{2,}(?P<Col4>.*)((?P<Col5>.*))'
mydf.Col2.str.extract(regex, expand=True).combine_first(mydf)
Col1 Col2 Col3 Col4 Col5
0 AA AN log1 Ind 0.9
1 AB LN log2 RED 8.9
2 AAC RN log3 RED 9.8
说明
这使用正则表达式解析Col2
值并同时分配列名
regex = '(?P<Col2>.*)|{2,}(?P<Col4>.*)((?P<Col5>.*))'
-
'(?P<Col2>.*)|{2,}'
将抓住所有内容到第一个双|
,并将其称为Col2
-
'(?P<Col4>.*)'
将所有内容抓住到括号,称其为Col4
-
'((?P<Col5>.*))'
抓住括号内的所有东西,称其为Col5
- 最后,我们要么重新调用
Col2
覆盖现有的Col2
,要么使用combine_first
,在其中默认为新配方的Col2
值。
@pirsquared答案像往常一样令人惊讶,并且投票,我只是在发布我的方法。我只是让它非常简单
mydf[['Col2', 'Col4', 'Col5']]= mydf.Col2.str.extract('(.*?)||(.*?)((.*?))', expand = True)
col2会自动重新分配,因此以后不需要删除列。
Col1 Col2 Col3 Col4 Col5
0 AA AN log1 Ind 0.9
1 AB LN log2 RED 8.9
2 AAC RN log3 RED 9.8
使用从Great @pirsquared的解决方案
使用RegexIn [59]: regex = '(?P<Col2>.*)|{2,}(?P<Col4>.*)((?P<Col5>.*))'
In [60]: mydf = mydf.join(mydf.pop('Col2').str.extract(regex, expand=True))
.sort_index(axis=1)
In [61]: mydf
Out[61]:
Col1 Col2 Col3 Col4 Col5
0 AA AN log1 Ind 0.9
1 AB LN log2 RED 8.9
2 AAC RN log3 RED 9.8