列标题中的多个分隔符也会分隔行值

时间:2017-08-15 18:21:30

标签: python pandas delimiter delimited-text

我在阅读文件时遇到了一些关于定义多个分隔符的问题。由于@piRsquared

,它最初在我之前的帖子reading-files-with-multiple-delimiter-in-column-headers-and-skipping-some-rows中解决了

当我详细查看我的真实数据时 意识到有些列有.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')

得到了这个输出!

enter image description here

1 个答案:

答案 0 :(得分:2)

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

Vi

旧答案

我使用Uj&&作为解析您所展示内容的快捷方式。下面我使用了一些比你需要的实际分隔符更具体的东西。

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