python - 使用 pandas read_csv 时将分隔符限制为仅某些选项卡

标签 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

我打算尝试将标签作为一个单独的列来读取,我想我可以通过为分隔符传递一个正则表达式来做到这一点,它排除了标签上下文中出现的制表符。

正在关注 http://www.rexegg.com/regex-best-trick.html我为此编写了以下正则表达式:[A-Za-z][A-Za-z0-9]:[A-Za-z]:[^\t]+\t..:|(\t)。我在在线正则表达式测试器上对其进行了测试,它似乎正好匹配我想要作为分隔符的制表符。

但是当我运行的时候

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)

我得到此数据的以下输出:

                          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 亿多行。

最佳答案

我快速浏览了一下 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
                              ^    ^  ^                ^           

您只需要匹配前 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 个字符集

=> 匹配第 4 个标签

Demo

Note

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

关于python - 使用 pandas read_csv 时将分隔符限制为仅某些选项卡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34658252/

相关文章:

python - GridseachCV - 值错误 : Found input variables with inconsistent numbers of samples: [33 1]

javascript - 正则表达式接受至少 6 个字符,至少一个字母和以下至少之一 : 0123456789-. @_

python - 属性错误: 'str' object has no attribute 'isnumeric'

python - 修补作为另一个类的属性的类实例属性

python - 来自 tkinter 应用程序的多线程

python - 正则表达式与 Python 中的\t\n\r\f\v 不匹配

python - pd.to_datetime 或解析日期时间不适用于我的 csv 文件(格式 : dd/mm/yyyy, hh:mm:ss)

python - hub_table 没有给出预期的结果

python - 防止用户转到任何其他 URL

javascript - 使用正则表达式验证 jquery 选择器语法