smi*_*ley 5 python regex pandas
我正在使用read_csv将一些制表符分隔的数据读入pandas Dataframe,但我在列数据中出现了标签,这意味着我不能只使用"\ t"作为分隔符.具体来说,每行中的最后一个条目是一组制表符分隔的可选标记,它们匹配[A-Za-z] [A-Za-z0-9]:[A-Za-z] :. +没有任何保证将有多少标签或将存在哪些标签,并且不同的标签可以出现在不同的行上.示例数据如下所示(所有空格都是我数据中的选项卡):
C42TMACXX:5:2316:15161:76101 163 1 @<@DFFADDDF:DD NH:i:1 HI:i:1 AS:i:200 nM:i:0
C42TMACXX:5:2316:15161:76101 83 1 CCCCCACDDDCB@B NH:i:1 HI:i:1 nM:i:1
C42TMACXX:5:1305:26011:74469 163 1 CCCFFFFFHHHHGJ NH:i:1 HI:i:1 AS:i:200 nM:i:0
Run Code Online (Sandbox Code Playgroud)
我建议尝试将标签作为单个列读取,我想我可以通过传递分隔符的正则表达式来完成此操作,该分隔符排除了在标签上下文中出现的标签.
关于http://www.rexegg.com/regex-best-trick.html,我为此写了以下正则表达式:[A-Za-z] [A-Za-z0-9]:[A-Za-z] :[^ \吨] + \吨..:|(\吨).我在一个在线正则表达式测试器上测试它,它似乎只是匹配我想要的选项卡作为分隔符.
但是当我跑步的时候
df = pd.read_csv(myfile.txt, sep=r"[A-Za-z][A-Za-z0-9]:[A-Za-z]:[^\t]+\t..:|(\t)",
header=None, engine="python")
print(df)
Run Code Online (Sandbox Code Playgroud)
我得到这个数据的以下输出:
0 1 2 3 4 5 6 7 8 \
0 C42TMACXX:5:2316:15161:76101 \t 163 \t 1 \t @<@DFFADDDF:DD \t NaN
1 C42TMACXX:5:2316:15161:76101 \t 83 \t 1 \t CCCCCACDDDCB@B \t NaN
2 C42TMACXX:5:1305:26011:74469 \t 163 \t 1 \t CCCFFFFFHHHHGJ \t NaN
9 10 11 12 13 14
0 NaN i:1 \t NaN NaN i:0
1 NaN i:1 \t nM:i:1 NaN None
2 NaN i:1 \t NaN NaN i:0
Run Code Online (Sandbox Code Playgroud)
我期待/想要的是:
0 1 2 3 4
0 C42TMACXX:5:2316:15161:76101 163 1 @<@DFFADDDF:DD NH:i:1 HI:i:1 AS:i:200 nM:i:0
1 C42TMACXX:5:2316:15161:76101 83 1 CCCCCACDDDCB@B NH:i:1 HI:i:1 nM:i:1
2 C42TMACXX:5:1305:26011:74469 163 1 CCCFFFFFHHHHGJ NH:i:1 HI:i:1 AS:i:200 nM:i:0
Run Code Online (Sandbox Code Playgroud)
怎么做到的?
如果它是相关的,我使用pandas 0.17.1并且我的真实数据文件大约是1亿+行.
我快速浏览了 pandas 文档,似乎用作分隔符的正则表达式不能使用组。
C42TMACXX:5:2316:15161:76101 163 1 @<@DFFADDDF:DD NH:i:1 HI:i:1 AS:i:200 nM:i:0
C42TMACXX:5:2316:15161:76101 83 1 CCCCCACDDDCB@B NH:i:1 HI:i:1 nM:i:1
C42TMACXX:5:1305:26011:74469 163 1 CCCFFFFFHHHHGJ NH:i:1 HI:i:1 AS:i:200 nM:i:0
^ ^ ^ ^
Run Code Online (Sandbox Code Playgroud)
您只需匹配前 4 个选项卡,但如果不使用组则无法匹配。
解决方案是\t通过使用前瞻和后瞻来隔离所需内容。
这是一个应该有效的正则表达式:
(?<=\d)\t(?=\d)|\t(?=[A-Z@<:]{14})|(?<=[A-Z@<:]{14})\t
解释
(?<=\d)\t(?=\d):制表符,前面有(?<=...)一个数字,后面有(?=...)一个数字
=> 匹配第一个和第二个选项卡
|或者
\t(?=[A-Z@<:]{14}):制表符后跟 LETTER、@、< 或 集中出现的 14 个连续字符:
=> 匹配第三个选项卡
|或者
(?<=[A-Z@<:]{14})\t:制表符前面带有相同的 14 个字符集
=> 匹配第四个选项卡
笔记
如果您需要在 14 个连续字符模式中允许更多字符,只需将它们添加到集合中即可。