Python 在pandas中读取csv时自动确定标题行

Python 在pandas中读取csv时自动确定标题行,python,pandas,csv,Python,Pandas,Csv,我试图从不同的.csv文件中收集数据,这些文件共享相同的列名。但是,某些csv文件的标题位于不同的行中 是否有一种方法可以根据包含“most”值的第一行(实际标题名称)动态确定标题行 我尝试了以下方法: def process_file(file, path, col_source, col_target): global df_master print(file) df = pd.read_csv(path + file, encoding = "ISO-8859-1"

我试图从不同的.csv文件中收集数据,这些文件共享相同的列名。但是,某些csv文件的标题位于不同的行中

是否有一种方法可以根据包含“most”值的第一行(实际标题名称)动态确定标题行

我尝试了以下方法:

def process_file(file, path, col_source, col_target):
    global df_master
    print(file)
    df = pd.read_csv(path + file, encoding = "ISO-8859-1", header=None)
    df = df.dropna(thresh=2) ## Drop the rows that contain less than 2 non-NaN values. E.g. metadata
    df.columns = df.iloc[0,:].values
    df = df.drop(df.index[0])
但是,当使用pandas.read_csv()时,当我收到以下错误消息时,第一个值似乎决定了实际数据帧的大小:

pandas.errors.ParserError:标记数据时出错。C错误:应为1 第4行中的字段,saw 162

正如您在本例中看到的,标题行应该位于第4行。 当添加
error\u bad\u lines=False
以读取\u csv时,只有元数据将被读取到数据帧中

这些文件可以具有以下结构之一:

“普通”文件:

或在标题之前包含元数据的结构:

row1   metadata1    
row2   metadata2
row3   col1   col2    col3    col4   col5
row4   val1   val1    val1    val1   val1

非常感谢任何帮助

有点脏,但这样行得通。基本上,它包括尝试读取文件,忽略从0到整个文件的顶部行。一旦csv有了可能,它就会返回它。 根据您的需要调整定制的csv

import pandas as pd

def file_len(fname):
    with open(fname) as f:
        for i, l in enumerate(f):
            pass
    return i + 1

def custom_csv(fname):
    _file_len = file_len(fname)
    for i in range(_file_len):
        try:
            df = pd.read_csv(fname, skiprows=i)
            return df
        except Exception:
            print(i)
    return 
print(custom_csv('pollution.csv'))

有点脏,但这个管用。基本上,它包括尝试读取文件,忽略从0到整个文件的顶部行。一旦csv有了可能,它就会返回它。 根据您的需要调整定制的csv

import pandas as pd

def file_len(fname):
    with open(fname) as f:
        for i, l in enumerate(f):
            pass
    return i + 1

def custom_csv(fname):
    _file_len = file_len(fname)
    for i in range(_file_len):
        try:
            df = pd.read_csv(fname, skiprows=i)
            return df
        except Exception:
            print(i)
    return 
print(custom_csv('pollution.csv'))

我想暂时忘记熊猫最简单的方法是:

  • 您可以将该文件作为文本文件打开以进行读取
  • 你开始一行一行地分析它,猜测这行是否正确
    • 元数据头
    • 真正的标题行
    • 数据线

一种简单的方法是将从真实标题行开始的所有行串联在一个字符串中(我们称之为
buffer
),然后使用
pd.read\u csv(io.StringIO(buffer),…)

如果暂时忘记熊猫,最简单的方法是:

  • 您可以将该文件作为文本文件打开以进行读取
  • 你开始一行一行地分析它,猜测这行是否正确
    • 元数据头
    • 真正的标题行
    • 数据线

一种简单的方法是将从真正的头行开始的所有行串联在一个字符串中(我们称之为
buffer
),然后使用
pd.read\u csv(io.StringIO(buffer),…)
这就是我所做的。它不会像我试过的其他东西那样给你假阳性。您基本上不希望行中出现空记录

  • 创建您的数据帧(下面的df)并将其标题索引设置为0
  • 现在,反复浏览它:

    if df is not False:
        ind = 0
        notfound = True
    
        while notfound:
            for index, row in df.iterrows():
                s = pd.Series(row)
                if s.isnull().values.any():
                    ind += 1
                else:
                    notfound = False
                    break
        return ind
    else:
        return False
    
  • 重新生成数据帧,但将从上面的+1返回的标题索引传递给它。因此,如果它返回ind=5,则通过6


  • 这就是我所做的。它不会像我试过的其他东西那样给你假阳性。您基本上不希望行中出现空记录

  • 创建您的数据帧(下面的df)并将其标题索引设置为0
  • 现在,反复浏览它:

    if df is not False:
        ind = 0
        notfound = True
    
        while notfound:
            for index, row in df.iterrows():
                s = pd.Series(row)
                if s.isnull().values.any():
                    ind += 1
                else:
                    notfound = False
                    break
        return ind
    else:
        return False
    
  • 重新生成数据帧,但将从上面的+1返回的标题索引传递给它。因此,如果它返回ind=5,则通过6


  • 更好的方法是使用csv嗅探搜索数据的起始位置,它上面的行将给出csv列标题

    import csv 
    import pandas as pd    
    Expected_Delimiter= "," 
    count =0
    
    with open(path,"r+") as f:
        while True:
            sniffer = csv.Sniffer()
            line = f.readline()
            count = count+1
            # Breaking the loop if file reaches eof
            if not (line):
                break
            Dialect =sniffer.sniff(line)
            file_Delimiter = Dialect.delimiter
            # Breaking loop if delimiter is found
            if (file_Delimiter == Expected_Delimiter):
                break
            else:
                continue
    
    skiprows = count -1     
    CSV_data = pd.read_csv(path,sep=Expected_Delimiter,skiprows =skiprows, encoding = "ISO-8859-1")
    

    更好的方法是使用csv嗅探搜索数据的起始位置,它上面的行将给出csv列标题

    import csv 
    import pandas as pd    
    Expected_Delimiter= "," 
    count =0
    
    with open(path,"r+") as f:
        while True:
            sniffer = csv.Sniffer()
            line = f.readline()
            count = count+1
            # Breaking the loop if file reaches eof
            if not (line):
                break
            Dialect =sniffer.sniff(line)
            file_Delimiter = Dialect.delimiter
            # Breaking loop if delimiter is found
            if (file_Delimiter == Expected_Delimiter):
                break
            else:
                continue
    
    skiprows = count -1     
    CSV_data = pd.read_csv(path,sep=Expected_Delimiter,skiprows =skiprows, encoding = "ISO-8859-1")
    

    这可能会有帮助:这可能会有帮助:我没想过。谢谢我没想过这个。谢谢