读取txt文件时考虑带空格的名称国家名称为多列

问题描述

我正在尝试将文本文件加载到 Python 中,但由于字符串中有多个单词的空格,它将每个单词视为一个单独的列。出了什么问题,我该如何解决

数据:

Name 2000–12 2012–13 2013–14 2012 2012 2012 2012 2012 2012 2012
Costa Rica 4.7 3.4 4.3 15.9 15.1 –5.3 –3.5 .. 4.5 49.4
Côte d’Ivoire 1.2 8.7 8.2 .. .. 2.0 –3.1 .. 1.3 39.0
Croatia 2.1 .. .. 18.9 9.3 –0.3 –4.7 .. 3.4 80.7
Cuba 5.8 .. .. .. .. .. .. .. .. ..
Curaçao .. .. .. .. .. .. .. .. .. ..
Cyprusb 2.6c .. .. 8.8c 3.9c –6.9 –6.3 113.3 2.4 ..
Czech Republic 3.3 .. .. 21.0 5.1 –2.4 –4.4 38.3 3.3 77.3
Denmark 0.6 .. .. 23.6 15.7 5.9 –2.0 50.6 2.4 74.6
Djibouti 3.5 .. .. .. .. .. .. .. 3.7 ..
Dominica 3.2 1.1 1.7 10.8 .. –11.5 –11.9 .. 1.4 97.4
Dominican Republic 5.6 2.5 3.9 9.2 .. –6.8 –2.9 .. 3.7 34.3
Ecuador 4.4 4.0 4.1 26.9 6.1 –0.2 .. .. 5.1 31.6
Egypt,arab Rep. 4.9 1.8 2.3 13.0 0.0 –2.7 –10.6 .. 7.1 74.1

到目前为止我尝试过的:

q3=pd.read_csv("E:\DRISTIA\Question2.txt",skiprows=2,encoding='unicode_escape',header=0,engine='python',skipinitialspace=True,delim_whitespace=True)
print(q3)

               Name 2000–12 2012–13 2013–14  2012 2012.1 2012.2 2012.3 2012.4  \
Costa          Rica     4.7     3.4     4.3  15.9   15.1   –5.3   –3.5     ..   
Côte       d’Ivoire     1.2     8.7     8.2    ..     ..    2.0   –3.1     ..   
Croatia         2.1      ..      ..    18.9   9.3   –0.3   –4.7     ..    3.4   
Cuba            5.8      ..      ..      ..    ..     ..     ..     ..     ..   
Curaçao          ..      ..      ..      ..    ..     ..     ..     ..     ..   
Cyprusb        2.6c      ..      ..    8.8c  3.9c   –6.9   –6.3  113.3    2.4   
Czech      Republic     3.3      ..      ..  21.0    5.1   –2.4   –4.4   38.3   
Denmark         0.6      ..      ..    23.6  15.7    5.9   –2.0   50.6    2.4   
Djibouti        3.5      ..      ..      ..    ..     ..     ..     ..    3.7   
Dominica        3.2     1.1     1.7    10.8    ..  –11.5  –11.9     ..    1.4   
Dominican  Republic     5.6     2.5     3.9   9.2     ..   –6.8   –2.9     ..   

注意如何例如“哥斯达黎加”和“科特迪瓦”等中的第二个词被推入第一个数据列。我希望那些留在名称栏中。

所需输出

Name       2000–12 2012–13 2013–14 2012 2012 2012 2012 2012 2012 2012
Costa Rica 4.7     3.4     4.3     15.9 15.1 –5.3 –3.5 ..   4.5  49.4

即Country name 的所有字符串都应位于 Name 列下。所有其他列都是常规列,不包含任何空格。

解决方法

Pandas read_csv function 接受自定义分隔符 sep,它可以是正则表达式。现在的任务是阐明一个仅匹配一行中最后 n-1 个空格的正则表达式,其中 n 是文件中的列数。

q3=pd.read_csv(
    "Question2.txt",engine='python',skiprows=2,encoding='unicode_escape',sep=r'\s+(?!\S+(?:\s+\S+){10})')
print(q3)

正则表达式匹配空格 (\s+),但前提是它后面没有跟 (?!...) 十个或更多空格分隔的列。

您提供的示例数据似乎与您的代码期望的不完全匹配,但是在顶部添加了几行空行,我明白了

                  Name 2000–12 2012–13  ... 2012.4 2012.5 2012.6
0           Costa Rica       4.7       3.4  ...     ..    4.5   49.4
1     Côte d’Ivoire       1.2       8.7  ...     ..    1.3   39.0
2              Croatia       2.1        ..  ...     ..    3.4   80.7
3                 Cuba       5.8        ..  ...     ..     ..     ..
4             Curaçao        ..        ..  ...     ..     ..     ..
5              Cyprusb      2.6c        ..  ...  113.3    2.4     ..
6       Czech Republic       3.3        ..  ...   38.3    3.3   77.3
7              Denmark       0.6        ..  ...   50.6    2.4   74.6
8             Djibouti       3.5        ..  ...     ..    3.7     ..
9             Dominica       3.2       1.1  ...     ..    1.4   97.4
10  Dominican Republic       5.6       2.5  ...     ..    3.7   34.3
11             Ecuador       4.4       4.0  ...     ..    5.1   31.6
12    Egypt,Arab Rep.       4.9       1.8  ...     ..    7.1   74.1

[13 rows x 11 columns]

(注意 Unicode mojibake,,因为 encoding 关键字参数有点奇怪。)

可能作为您的第一个任务以一种不那么愚蠢的格式保存结果,可能作为正确的 CSV(逗号分隔,在包含文字逗号的任何字段周围引用;但是 Pandas to_csv()为您处理所有这一切)。

顺便说一句,使用完整路径对文件名进行硬编码可能会使您的脚本变得不那么有用。也许取出路径,就像我上面所做的那样,并在您拥有输入文件的目录中运行脚本,或者(不太有用,但有时更实用)放入子目录的相对路径,然后从对应的父目录。