代码之家  ›  专栏  ›  技术社区  ›  vicemagui

使用glob按特定顺序导入文件

  •  2
  • vicemagui  · 技术社区  · 7 年前

    我有一个很长的时间序列,每年都存档在一个文件夹中,对应于今年。但是,在每个文件夹中,数据不是记录在单个文件中,而是记录在每月的文件中。

    e、 g.1954年>4月、8月、12月、9月

    当我使用Glob导入这些文件并用Pandas创建数据帧时,它们是按相同的顺序导入的(如上)。但是,相反,我需要一个正确的月份序列(1月、2月、3月…)来绘制和使用它们。所以,我的问题是:

        path = r'path'
        allFiles = glob.glob(path+"/*.dtf")
    
        df = pd.DataFrame()
        list_ = []
        for file_ in allFiles:
          df = pd.read_csv(file_,header = None,sep=r"\s*")
          list_.append(df)
        df = pd.concat(list_)
    

    谢谢

    3 回复  |  直到 7 年前
        1
  •  1
  •   jezrael    7 年前

    您可以使用 concat 带参数 keys 具有文件名:

    here .

    path = r'path-dtfs'
    #add /* for read subfolders
    allFiles = glob.glob(path+"/*/*.dtf")
    print (allFiles)
    ['path\\1954\\FEB.dtf', 'path\\1954\\JAN.dtf', 'path\\1955\\APR.dtf', 'path\\1955\\MAR.dtf']
    
    list_ = []
    for file_ in allFiles:
        df = pd.read_csv(file_,header = None,sep=r"\s+")
        list_.append(df)
    

    然后通过创建新列 split insert ordered categorical 具有 sort_values :

    df = pd.concat(list_, keys=allFiles)
           .reset_index(level=1, drop=True)
           .rename_axis('years').reset_index()
    
    s = df['years'].str.split('\\')
    df['years'] = s.str[-2].astype(int)
    df.insert(1, 'months', s.str[-1].str.replace('.dtf', ''))
    
    #add all missing months
    cats = ['JAN','FEB','MAR','APR']
    df['months'] = df['months'].astype('category', categories=cats, ordered=True)
    df = df.sort_values(['years','months']).reset_index(drop=True)
    print (df)
       years months  0  1  2
    0   1954    JAN  0  1  2
    1   1954    JAN  1  5  8
    2   1954    FEB  0  9  6
    3   1954    FEB  1  6  4
    4   1955    MAR  5  6  8
    5   1955    MAR  4  7  9
    6   1955    APR  0  3  6
    7   1955    APR  1  4  1
    

    另一个解决方案是创建 datetime str.extract 具有 to_datetime :

    df = pd.concat(list_, keys=allFiles)
           .reset_index(level=1, drop=True)
           .rename_axis('dates')
           .reset_index()
    df['dates'] = df['dates'].str.extract('path\\\(.*).dtf', expand=False)
    df['dates'] = pd.to_datetime(df['dates'], format='%Y\%b')
    df = df.sort_values('dates').reset_index(drop=True)
    print (df)
           dates  0  1  2
    0 1954-01-01  0  1  2
    1 1954-01-01  1  5  8
    2 1954-02-01  0  9  6
    3 1954-02-01  1  6  4
    4 1955-03-01  5  6  8
    5 1955-03-01  4  7  9
    6 1955-04-01  0  3  6
    7 1955-04-01  1  4  1
    

    month period 通过 to_period

    df = pd.concat(list_, keys=allFiles)
           .reset_index(level=1, drop=True)
           .rename_axis('periods').reset_index()
    df['periods'] = df['periods'].str.extract('path\\\(.*).dtf', expand=False)
    df['periods'] = pd.to_datetime(df['periods'], format='%Y\%b').dt.to_period('M')
    df = df.sort_values('periods').reset_index(drop=True)
    
    print (df)
      periods  0  1  2
    0 1954-01  0  1  2
    1 1954-01  1  5  8
    2 1954-02  0  9  6
    3 1954-02  1  6  4
    4 1955-03  5  6  8
    5 1955-03  4  7  9
    6 1955-04  0  3  6
    7 1955-04  1  4  1
    
        2
  •  1
  •   piRSquared    7 年前

    您可以使用函数作为 key 排序列表时

    allFiles 我们(感谢jezrael提供的样本列表):

    allFiles = ['path/1954/FEB.dtf', 'path/1954/JAN.dtf',
                'path/1955/APR.dtf', 'path/1955/MAR.dtf']
    

    然后将密钥定义为

    d = dict(JAN=0, FEB=1, MAR=2, APR=3)
    
    def key(path):
        y, m = path.rsplit('.', 1)[0].split('/')[-2:]
        return int(y), d[m]
    

    在python中使用它 sorted 作用

    sorted(allFiles, key=key)
    
    ['path/1954/JAN.dtf',
     'path/1954/FEB.dtf',
     'path/1955/MAR.dtf',
     'path/1955/APR.dtf']
    

    allFiles.sort(key=key)
    

    您可以在导入时使用它:

    pd.concat(
        [pd.read_csv(file_,header = None,sep=r"\s*")
         for file_ in sorted(allFiles, key=key)]
    )
    
        3
  •  1
  •   Bharath M Shetty    7 年前

    您可以使用 sorted 月份指数为 key

    import os
    path = r'path'
    months = ["JAN","FEB","MAR","APR","MAY","JUN","JULY","AUG","SEP","OCT","NOV","DEC"]
    allfiles= sorted(glob.glob(path+"/*.dtf"), key=lambda filename: [months.index(os.path.splitext(os.path.basename(filename))[0])])
    
    df = pd.DataFrame()
    list_ = []
    for file_ in allFiles:
      df = pd.read_csv(file_,header = None,sep=r"\s*")
      list_.append(df)
    df = pd.concat(list_)
    

    希望这有帮助