处理具有多个独立标题的CSV文件

1 投票
4 回答
74 浏览
提问于 2025-04-12 15:42

我刚开始学习Python(还有Stack Overflow这个网站),现在想处理一个CSV文件,这个文件分成两个部分,每个部分都有自己的表头,而且长度不同。

第一部分只有两行:一行是有13列的表头,第二行是数据。

在两行空行之后,第二部分开始了,先是一个表头,这次有42个条目,后面跟着不定数量的数据行。

看看这个(简化过的)例子:

A B C D E F G H
1 文件名 日期 时间 编号 类型
2 report.csv 2024年3月27日 11:15 12345 东西
3  
4  
5 编号 设备 版本 读数日期 读数时间 值1 值2 值3
6 1 2345678 10 2024年3月26日 10:00 463 470 482
7 2 3456789 11 2024年3月26日 11:00 298 340 363
8 3 4567890 12 2024年3月26日 12:00 587 600 621
9 ...

我想做的是把这两个部分当作两个独立的东西来处理,并为每个部分创建一个字典,最好不需要创建任何“辅助”文件(比如把它分成两个单独的CSV文件)。到目前为止,我尝试了很多方法,比如用csv.DictReaderpandas.read_csv配合设置chunksize或者给header参数传递一系列行索引。但我在网上搜索了一个小时,还是找不到有类似问题的人。

4 个回答

0

使用标准的csv库(不是pandas),你可以通过在for循环中使用'next'命令来跳过你需要的任意数量的表头行。下面的代码展示了如何打开一个文件并跳过你需要的行数(在这个例子中是跳过5行)

import csv

reader = csv.reader(open('test.csv'), delimiter=';')

for row in range(5):
    next(reader) # skip header line

# start displaying for the 6th row
for row in reader:
    print(row)

如果表头的行数不固定,你可以在读取文件时循环检查,找到包含你数据实际表头的那一行。你可以通过检查第一列的值来寻找表头的名称:

import csv 

reader = csv.reader(open('test.csv'), delimiter=';')

for row in reader:
    # check the row is not empty and check for 1st column (row[0])
    if row !=[] and row[0] == 'first_col_header':
         print (row)
1

python 3.11.5 pandas 2.2.1

我们可以用 csv.reader 来按顺序加载数据。

假设我们有一个csv文件,里面的数据是这样的:

import csv, io

raw_data = '''File name,Date,Time,ID,Type
report.csv,27.03.2024,11:15,12345,Thing


No.,Device,Version,Readout date,Readout time,Value 1,Value 2,Value 3
1,2345678,10,26.03.2024,10:00,463,470,482
2,3456789,11,26.03.2024,11:00,298,340,363
3,4567890,12,26.03.2024,12:00,587,600,621
'''

data = csv.reader(io.StringIO(raw_data))

我们可以通过读取前两行直接创建第一个字典:

first_table = dict(zip(next(data), next(data)))

要获取下一个字典,我们可以使用 pandas.DataFrame,但首先得跳过空行:

import pandas as pd

for line in data:
    if line:
         break
df = pd.DataFrame(data, columns=line)

或者,为了更保险一点:

for line in data:
    if any(cell.strip() for cell in line):
         break
else:
    raise(ValueError('No data for the second table found'))
    
df = pd.DataFrame(data, columns=line)

如果不能使用Pandas,我们可以像之前那样,通过将表头和其他数据配对来创建一个字典:

for headers in data:
    if any(cell.strip() for cell in headers):
        break
columns = zip(*data)
second_table = dict(zip(headers, columns))

可以尝试的代码:

from csv import reader
from itertools import takewhile

data = reader(open('data.csv'))
tables = []

for record in data:
    if record:   
        headers = record
        rows = takewhile(bool, data)
        columns = map(list, zip(*rows))
        tables.append(dict(zip(headers, columns)))
0

你可以很简单地用 .iloc 函数来分割这个 CSV 文件。首先,你需要把 CSV 文件读成一个数据框(dataframe):

import pandas as pd
my_csv = pd.read_csv('my_csv.csv')

接下来,创建两个变量,用来定义数据框的不同部分,作为新的数据框,比如:

df1 = my_csv[:3]
df2 = my_csv[5:]

如果列名没有正确读取,你需要单独给列命名,比如:

df1.columns = ['No. Device', 'Version', 'Readout date', 'Readout time', 'Value 1',  'Value 2',  'Value 3']

希望这些对你有帮助

撰写回答