【问题标题】:Multiple delimiters in column headers also separates the row values列标题中的多个分隔符也分隔行值
【发布时间】:2018-01-23 17:48:21
【问题描述】:

我在读取文件时遇到了一些关于定义多个分隔符的问题。它最初在我之前的帖子reading-files-with-multiple-delimiter-in-column-headers-and-skipping-some-rows 中解决,感谢@piRsquared

当我详细查看我的真实数据时,我 意识到某些列具有 .cd 或 .dvd 扩展名,当我应用上面的解决方案时,它们也被分离为一个新列,上面的解决方案开始不起作用!

b.txt

skip1
 A1| A2 |A3 |A4# A5# A6 A7| A8 , A9
1,2,3,4,5.cd,6,7,8.dvd,9
1,2,3,4,5.cd,6,7,8.dvd,9
1,2,3,4,5.cd,6,7,8.dvd,9

END123
Some other data starts from here

并使用上面的solution 读取这个 b.txt 文件

txt = open('b.txt').read().split('\nEND')[0]
pd.read_csv(
    pd.io.common.StringIO(txt),
    sep=r'\W+',
    skiprows=1,index_col=False, engine='python')

   A1  A2  A3  A4  A5  A6  A7  A8  A9
0   1   2   3   4   5  cd   6   7   8
1   1   2   3   4   5  cd   6   7   8
2   1   2   3   4   5  cd   6   7   8

A5 列应该有行

5.cd
5.cd
5.cd

A9 列也一样

8.dvd
8.dvd
8.dvd

我们应该有 A9 列,但似乎由于这种冲突而消失了。

编辑:

我将几乎相似的身份与我的真实数据放在一起

 skip rows
 A1| A2| A3|A4# A5#  |  A6 | A7  , A8,  A9  | A10 |
 1 | 2 | 3 |4 # 5 #  | 6.cd|7.dvd,   ,      | 10  | 
 1 | 2 | 3 |4 # 5 #  | 6.cd|     ,   ,   9  | 10  |
 1 | 2 | 3 |4 # 5 #  |     |7.dvd,   ,      | 10  |

END123
Some other data starts from here

尝试过

txt = open('real_dat.txt').read().split('\nEND')[0]
_, h, txt = txt.split('\n', 2)
pat = r'[\|, ,#,\,]+'
names = re.split(pat, h.strip())

df=pd.read_csv(
    pd.io.common.StringIO(txt),
    names=names,skiprows=1,index_col=False,
    engine='python')

并得到这个输出!

【问题讨论】:

    标签: python pandas delimiter csv


    【解决方案1】:

    更新答案
    摆脱空格更容易......让我知道这是否有效

    txt = open('b.txt').read().split('\nEND')[0] \
        .replace(' ', '').replace('|\n', '\n').split('\n', 1)[1]
    
    pd.read_csv(
        pd.io.common.StringIO(txt),
        sep=r'#\||\||#|,',
        engine='python')
    
       A1  A2  A3  A4  A5    A6     A7  A8   A9  A10
    0   1   2   3   4   5  6.cd  7.dvd NaN  NaN   10
    1   1   2   3   4   5  6.cd    NaN NaN  9.0   10
    2   1   2   3   4   5   NaN  7.dvd NaN  NaN   10
    

    旧答案

    我使用\W+ 作为解析您显示的内容的快速简便的方法。下面我使用了一些更具体到您需要的实际分隔符。

    txt = open('b.txt').read().split('\nEND')[0]
    pd.read_csv(
        pd.io.common.StringIO(txt),
        sep=r'[\|, ,#,\,]+',
        skiprows=1,index_col=False, engine='python')
    
       A1  A2  A3  A4    A5  A6  A7     A8  A9
    0   1   2   3   4  5.cd   6   7  8.dvd   9
    1   1   2   3   4  5.cd   6   7  8.dvd   9
    2   1   2   3   4  5.cd   6   7  8.dvd   9
    

    但是,我仍然认为这是一种更清洁的方式。在这里,我将标头的解析与其余数据的解析分开。这样,我假设数据应该只使用, 作为分隔符。

    txt = open('b.txt').read().split('END')[0]
    _, h, txt = txt.split('\n', 2)
    pat = r'[\|, ,#,\,]+'
    names = re.split(pat, h.strip())
    
    pd.read_csv(
        pd.io.common.StringIO(txt),
        names=names, header=None,
        engine='python')
    
       A1  A2  A3  A4    A5  A6  A7     A8  A9
    0   1   2   3   4  5.cd   6   7  8.dvd   9
    1   1   2   3   4  5.cd   6   7  8.dvd   9
    2   1   2   3   4  5.cd   6   7  8.dvd   9
    

    【讨论】:

    • 很抱歉再次打扰您。但是我一直在尝试您的解决方案一个多小时,发现现在只有第一个解决方案适用于我的真实数据:) 我不知道为什么后一个解决方案不起作用!
    • 我假设数据都是逗号分隔的。也许不是。此外,如果您可以将问题减少到仅不起作用的数据,我们可以修复它。不要担心“打扰”我。我可以选择帮助或不帮助。如果我选择帮忙,那你就不会打扰我了(-:
    • 不,您需要将\t 放在方括号内。这是正则表达式语法并且超越了 python。正则表达式非常强大,可能会非常混乱。 sep=r'[\t,\|, ,#,\,]+'
    • 这是试图找到一个可以解析数据和标题的神奇正则表达式的直接结果。我们目前的分隔符一次可以使用一个或多个逗号、条形、哈希或空格。为了区分'A7| A8''A5# A6',我允许了几个。但这妨碍了并将,, 解释为单个分隔符而不是 2。我建议您再次尝试解决方案 2,当它不起作用时,发布最少量的样本数据来重现问题。在那之前,我一直在尝试找到能够解析标头和数据的神奇正则表达式。
    • 好的,所以你确实需要神奇的子弹正则表达式。我会努力的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 2013-06-07
    • 2015-07-06
    • 2021-05-14
    • 2014-01-04
    • 1970-01-01
    • 2016-11-01
    相关资源
    最近更新 更多