【问题标题】:Python Pandas, Reading in file and skipping rows ahead of headerPython Pandas,读取文件并在标题前跳过行
【发布时间】:2018-11-27 13:43:51
【问题描述】:

我正在尝试遍历一些文件并使用 pandas 跳过每个文件中标题之前的行。所有文件都采用相同的数据格式,除了有些文件在标题之前要跳过的行数不同。当一些文件比其他文件有更多的行要跳过时,有没有办法循环文件并从每个文件的标题开始?

例如, 有些文件需要这个:

f = pd.read_csv(fname,skiprows = 7,parse_dates=[0])

有些人要求这样做:

f = pd.read_csv(fname,skiprows = 15, parse_dates=[0])

这是我在文件中循环的代码块:

for name,ID in stations:
    path = str(ID)+'/*.csv'
    for fname in glob.glob(path):
        print(fname)
        f = pd.read_csv(fname,skiprows=15,parse_dates=[0]) #could also skip 7 depending on file
        ws = f['Wind Spd (km/h)']*0.27778 #convert to m/s from km/h
        dt = f['Date/Time']

【问题讨论】:

  • 如何知道何时到达标题?标题上方的行总是空的吗?
  • 是的,标题上方有几行空行,但空行数也因文件而异。我知道当标题的第一个字段以日期/时间开头时我已经到达标题

标签: python pandas loops csv


【解决方案1】:

第一个建议/答案似乎是处理它的一种非常好的方法,但由于某种原因我无法让它为我工作。我确实找到了另一种方法来使用 python 中的 try 和 except 函数来解决我的问题:

for name,ID in stations:
    #read in each stations .csv files, concatenate together, insert station id column
    path = str(ID)+'/*.csv'
    for fname in glob.glob(path):
        print(fname)
        try:
            f = pd.read_csv(fname,skiprows=7,parse_dates=[0])
        except:
            f = pd.read_csv(fname,skiprows=15,parse_dates=[0])
        ws = f['Wind Spd (km/h)']*0.27778 #convert to m/s from km/h
        dt = f['Date/Time']

这样,如果第一次尝试读取文件失败(跳过 7 行),那么它会使用另一条 read_csv 行再次尝试(跳过 15 行)。这不是 100% 正确的,因为我仍在硬编码要跳过的行数,但现在可以满足我的需要。

【讨论】:

    【解决方案2】:

    一种方法是使用纯 Python I/O 读取文件以提取索引,然后将其输入到 pd.read_csvskip_rows 参数中。

    这是相当有效的,因为第一步使用了一个生成器表达式,它只在到达所需的行之前读取。

    from io import StringIO
    import pandas as pd
    from copy import copy
    
    mystr = StringIO("""dasfaf
    kgafsda
    
    
    Date/Time,num1,num2
    2018-01-01,0,1
    2018-01-02,2,3
    """)
    
    mystr2 = copy(mystr)
    
    # replace mystr with open('file.csv', 'r')
    with mystr as fin:
        idx = next(i for i, j in enumerate(fin) if j.startswith('Date/Time'))
    
    # replace mystr2 with 'file.csv'
    df = pd.read_csv(mystr2, skiprows=idx-1, parse_dates=[0])
    
    print(df)
    
       Date/Time  num1  num2
    0 2018-01-01     0     1
    1 2018-01-02     2     3
    

    如果您需要重复该任务,请将其包装在一个函数中:

    def calc_skiprows(fname):
        with fname as fin:
            idx = next(i for i, j in enumerate(fin) if j.startswith('Date/Time')) - 1
    
    df = pd.read_csv(fname, skiprows=calc_skiprows(fname), parse_dates=[0])
    

    【讨论】:

    • 谢谢,但是文件的标题前的行不是全是空行,只有标题前的几行是空白的,其余的都是单词。
    • 第5行有错别字吗?
    • @HM14,抱歉 - 已修复。
    • 我对此有点困惑。循环文件时,这一切都会循环吗?我已经编辑了我的问题以包含我用来循环我的文件的循环
    • @HM14,只需将逻辑包装在一个函数中,请参阅更新。
    猜你喜欢
    • 1970-01-01
    • 2020-08-29
    • 2012-03-23
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    • 2020-10-07
    • 2015-02-04
    相关资源
    最近更新 更多