首页 > 解决方案 > 如何自动化从具有多个部分的 CSV 文件中读取的脚本?

问题描述

我在一个包含整数和非整数行的文本文件中有数据,示例数据如下所示:

2012    10  6   3   57  22.3    33.18   73.71   0
KP  EP  3   57  36.36               
CET ES  3   58  17.22               
CET EP  3   57  55.12               
DHL ES  3   58  3.62                
2015    10  4   7   42  58  33.17   73.74   1.1
PDA EP  7   43  8.6             
NPR ES  7   43  27.98               
PAL EP  7   43  20.93               
CET ES  7   43  52.31               
CET EP  7   43  30.46               
2009    10  4   11  19  4.6 33.16   73.71   0
CET ES  11  19  59.6                
CET EP  11  19  37.12               
THW EP  11  19  37      

在上述情况下,我的数据有 3 组,每组有一个非整数行和一个可变数量(2、6、10、15、40 等)的非整数行。我需要编写代码来连接第一组整数和非整数行并将其保存在文本文件中。然后,它获取第二组并重复相同的过程,并将其再次保存在同一文本文件中,然后是第一组,依此类推。

(为清楚起见,我以更通用的方式修改了我的问题,以便每个人都可以轻松理解)。

标签: python

解决方案


您想读取一个包含多个部分的输入文件,每个部分都是一个单独的 CSV 文件。这里有两种方法;如果您是初学者,半自动实现 a) 将比自动化 b) 容易得多。

a) 最简单:只需获取每个部分的起始行和长度,然后将它们传递给pd.read_csv(..., nrows=..., skiprows=...)

看到这个答案

您可以通过以下方式找到每个部分的起始行:

`egrep -n '^[0-9]' the.csv`
1:2012    10  6   3   57  22.3    33.18   73.71   0
6:2015    10  4   7   42  58  33.17   73.74   1.1
12:2009    10  4   11  19  4.6 33.16   73.71   0

请注意 egrep 从 1 开始计数,但 Python 从 0 开始计数,因此您的起始行将是 [0,5,11]

>>> pd.read_csv('the.csv', skiprows=0, nrows=4)
  2012    10  6   3   57  22.3    33.18   73.71   0
0              KP  EP  3   57  36.36               
1              CET ES  3   58  17.22               
2              CET EP  3   57  55.12               
3              DHL ES  3   58  3.62                

>>> pd.read_csv('the.csv', skiprows=5, nrows=5)
  2015    10  4   7   42  58  33.17   73.74   1.1
0                PDA EP  7   43  8.6             
1            NPR ES  7   43  27.98               
2            PAL EP  7   43  20.93               
3            CET ES  7   43  52.31               
4            CET EP  7   43  30.46               

>>> pd.read_csv('the.csv', skiprows=11, nrows=9999)
  2009    10  4   11  19  4.6 33.16   73.71   0
0          CET ES  11  19  59.6                
1          CET EP  11  19  37.12               
2                         THW EP  11  19  37  

b) 更难:编写一个 Python生成器 multiple_csv_section_reader(),它:

  • 从输入中分别读取每个 CSV 部分,并将yield其作为一个块发送。然后,您可以将此块传递给pd.read_csv(StringIO(...))
  • 当看到带有整数(5 个整数和 3 个浮点数)的标题行时,检测新 CSV 部分的开始...
  • 然后将下一部分的标题行推回输入。

此外,将所有绘图代码移至单独的函数中,我们不需要查看它。


推荐阅读