【问题标题】:How to parse txt.file with no clear separator如何解析没有明确分隔符的 text.file
【发布时间】:2019-09-13 10:20:22
【问题描述】:

我正在尝试解析具有已知结构的 txt.file。 每列代表一个国家,每个值代表该名称在该国家/地区的使用频率。

关于源的更多信息加上原始文档here - 它被称为 nam_dict.txt

看起来像这样:

M  Aadam                                          1                                   $
F  Aadje                                1                                             $
M  Ådne                      +                 1                                      $
M  Aadu                                           12                                  $
?F Aaf                                  1                                             $
F  Aafke                                4                                             $
?  Aafke                                 1                                            $
F  Aafkea                                1                                            $
M  Aafko                                1                                             $
M  Aage                                       761                                     $
M  Åge                       +                56                                      $
F  Aagje                              1 2                                             $

问题是数字之间没有分隔符,给定列的任何数字都可能有一个或两个数字(1 到 13)。有什么好的方法可以提取吗?

我想用 Python 和 Pandas 来做这件事。

列如下:

['GreatBritain',
 'Ireland',
 'U.S.A.',
 'Italy',
 'Malta',
 'Portugal',
 'Spain',
 'France',
 'Belgium',
 'Luxembourg',
 'theNetherlands',
 'EastFrisia',
 'Germany',
 'Austria',
 'Swiss',
 'Iceland',
 'Denmark',
 'Norway',
 'Sweden',
 'Finland',
 'Estonia',
 'Latvia',
 'Lithuania',
 'Poland',
 'CzechRepublic',
 'Slovakia',
 'Hungary',
 'Romania',
 'Bulgaria',
 'BosniaandHerzegovina',
 'Croatia',
 'Kosovo',
 'Macedonia',
 'Montenegro',
 'Serbia',
 'Slovenia',
 'Albania',
 'Greece',
 'Russia',
 'Belarus',
 'Moldova',
 'Ukraine',
 'Armenia',
 'Azerbaijan',
 'Georgia',
 'Kazakhstan/Uzbekistan,etc.',
 'Turkey',
 'Arabia/Persia',
 'Israel',
 'China',
 'India/SriLanka',
 'Japan',
 'Korea',
 'Vietnam',
 'othercountries']

希望得到这种类型的输出(适当的数字):

    gender  GreatBritain    Ireland U.S.A.  Italy   Malta   Portugal    Spain   France  Belgium ... Kazakhstan/Uzbekistan,etc.  Turkey  Arabia/Persia   Israel  China   India/SriLanka  Japan   Korea   Vietnam othercountries
name                                                                                    
Aad M   NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Aadam   M   NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Aadje   F   NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Ådne    M   NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Aadu    M   NaN NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

【问题讨论】:

    标签: python pandas parsing text


    【解决方案1】:

    空格可以组合: df = pd.read_csv(filename, sep="\s+")

    例如随后的几个空格将被视为单个分隔符。

    更新:看来你应该使用read_fwf

    >>> df = pd.read_fwf('nam_dict.txt', header=None, skiprows=362)
    >>> df.head()
      0      1    2    3    4    5    6   7   8   9   10   11  12 13
    0  M    Aad  NaN  NaN  NaN    4  NaN NaN NaN NaN NaN  NaN NaN  $
    1  M  Aadam  NaN  NaN  NaN  NaN    1 NaN NaN NaN NaN  NaN NaN  $
    2  F  Aadje  NaN  NaN  NaN    1  NaN NaN NaN NaN NaN  NaN NaN  $
    3  M   Ådne    +  NaN  NaN  NaN    1 NaN NaN NaN NaN  NaN NaN  $
    4  M   Aadu  NaN  NaN  NaN  NaN   12 NaN NaN NaN NaN  NaN NaN  $
    >>> df.shape
    (48528, 14)
    

    Update2:必须生成列列表。第一列的宽度 = 1,第二列 = 27(直到 + 号),其余的设置为 1。如果需要,请检查并修改:

    >>> cols = [2, 27]
    >>> cols.extend([1]*58)
    >>> df = pd.read_fwf('nam_dict.txt', header=None, skiprows=362, widths=cols)
    >>> df.head()
      0      1    2    3   4   5    6    7    8    9  ...   50  51   52  53  54  \
    0  M    Aad  NaN  NaN NaN NaN  NaN  NaN  NaN  NaN ...  NaN NaN  NaN NaN NaN
    1  M  Aadam  NaN  NaN NaN NaN  NaN  NaN  NaN  NaN ...  NaN NaN  NaN NaN NaN
    2  F  Aadje  NaN  NaN NaN NaN  NaN  NaN  NaN  NaN ...  NaN NaN  NaN NaN NaN
    3  M   Ådne    +  NaN NaN NaN  NaN  NaN  NaN  NaN ...  NaN NaN  NaN NaN NaN
    4  M   Aadu  NaN  NaN NaN NaN  NaN  NaN  NaN  NaN ...  NaN NaN  NaN NaN NaN
    
        55   56  57  58 59
    0  NaN  NaN NaN NaN  $
    1  NaN  NaN NaN NaN  $
    2  NaN  NaN NaN NaN  $
    3  NaN  NaN NaN NaN  $
    4  NaN  NaN NaN NaN  $
    
    [5 rows x 60 columns]
    

    【讨论】:

    • 可以合并是什么意思?我试过你的建议,我得到 ParserError: Error tokenizing data。 C 错误:预计第 14 行中有 9 个字段,看到 12
    • 好的,它匹配任何非空白字符 - 虽然数字可能出现在不同的位置并且我想保留结构,但不能解决我的问题,数字所在的位置具有我的意义有兴趣检索
    • @MthClv 然后试试https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_fwf.html#pandas.read_fwf
    • pd.read_fwf('nam_dict.txt') 将所有内容压缩为一列 - 结构也丢失了
    • 实际上 pd.read_fwf('nam_dict.txt', skiprows=362, header=None) 返回 14 列是但我应该有 55 - 问题是彼此相邻的数字被理解为一个号码
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-30
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多