我正在使用 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,@,< 或 :
=> 匹配第三个标签
|
或者
(?<=[A-Z@<:]{14})\t
: 制表符前面有相同的 14 个字符集
=> 匹配第 4 个标签
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/