使用pandas read_cs时,将分隔符限制为仅某些制表符

2024-10-03 00:30:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用read_csv将一些制表符分隔的数据读入pandas数据帧,但列数据中有制表符,这意味着我不能只使用“\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

我建议尝试将标记作为一个单独的列读入,我认为可以通过为分隔符传递一个正则表达式来完成此操作,该分隔符排除了出现在标记上下文中的制表符。在

http://www.rexegg.com/regex-best-trick.html之后,我为此编写了以下正则表达式:[A-Za-z][A-Za-z0-9]:[A-Za-z]:[^\t]+\t..:|(\t)。我在一个在线正则表达式测试仪上测试了它,它似乎与我想要的分隔符选项卡匹配。在

但当我跑的时候

^{pr2}$

此数据的输出如下:

                          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  

我想要的是:

                          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

如何做到这一点?在

如果有关系的话,我使用的是pandas 0.17.1,我的实际数据文件大约是1亿行以上。在


Tags: 数据标记asnanhidd制表符分隔符
1条回答
网友
1楼 · 发布于 2024-10-03 00:30:51

我快速浏览了一下pandas文档,似乎regex用作分隔符不能使用组。在

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
                              ^    ^  ^                ^           

你只需要匹配前4个标签,但你不能不使用组。在

一个解决方案是使用lookaheads和lookbehind来隔离想要的\t。在

下面是一个应该有效的正则表达式:

(?<=\d)\t(?=\d)|\t(?=[A-Z@<:]{14})|(?<=[A-Z@<:]{14})\t

说明

(?<=\d)\t(?=\d):前面是(?<=...)一个数字,后面是(?=...)一个数字的制表符

=>;匹配第一个和第二个选项卡

|

\t(?=[A-Z@<:]{14}):后面紧跟14个连续字符的制表符@,@,<;或:

=>;匹配第三个选项卡

|

(?<=[A-Z@<:]{14})\t:前面有相同14个字符集的制表符

=>;匹配第四个选项卡

Demo

Note

If you need to allow more characters in the 14 consecutive characters pattern, just add them to the set.

相关问题 更多 >