【问题标题】:Pandas: Reading files with regexPandas:使用正则表达式读取文件
【发布时间】:2020-09-06 06:01:14
【问题描述】:

我正在尝试使用通配符读取多个 excel 文件,并使用 pandas 将其放入单独的数据帧中。

我已经阅读了基本路径并将使用下面来访问子目录:

>>>inputs_path
'C:/Users/ABC/Downloads/Input'
>>>path1 = os.chdir(inputs_path + "/path1")
>>>fls=glob.glob("*.*")
>>>fls

['Zambia_W4.xlsm',
 'Australia_W4.xlsx',
 'France_W4.xlsx',
 'Japan_W3.xlsm',
 'India_W3.xlsx',
 'Italy_W3.xlsx',
 'MEA_W5.xlsx',
 'NE_W5.xlsm',
 'Russia_W5.xlsx',
 'Spain_W2.xlsx']
>>>path2 = os.chdir(inputs_path + "/path2")
>>>fls=glob.glob("*.*")
>>>fls

['Today.xlsm',
 'Yesterday.xlsx',
 'Tomorrow.xlsx']

现在我正在阅读它们如下:

>>>df_italy = pd.read_excel("Italy_W3.xlsx",sheet_name='Sheet1')
>>>df_russia = pd.read_excel("Russia_W5.xlsx",sheet_name='Sheet3')
>>>df_france_1 = pd.read_excel("France_W4.xlsx",sheet_name='Sheet1', usecols = 'M, Q', skiprows=4)
>>>df_spain = pd.read_excel("Spain_W2.xlsx",sheet_name='Sheet2',usecols = 'T:U', skiprows=30 )
>>>df_ne = pd.read_excel("NE_W5.xlsm",sheet_name='Sheet2',usecols = 'N,P', skiprows=4 )
>>>df_ne_c = pd.read_excel("NE_W5.xlsm",sheet_name='Sheet1',usecols = 'H:J', skiprows=141 )

由于我在 fls 列表中有文件名,有没有一种方法可以使用该列表并读取文件,而不必实际使用实际文件名,因为文件名将根据周数更改。 在读取 excel 文件时,还必须保留上面提到的数据框名称。

我希望将文件读取为

>>>df_italy = pd.read_excel("Italy*.xlsx",sheet_name='Sheet1')

有什么办法吗?

【问题讨论】:

  • 您的文件是否始终遵循相同的约定,即country_week
  • 不,这不是强制性的,但可以肯定的是,国家名称将出现在文件中,无论是在开头还是中间。我已经从这里的实际文件名规范化了文件名。
  • 是每个国家/地区的前一周的文件都被删除了,还是需要从与该国家/地区相关的多个文件中找出最近一周的?
  • 如果当前一周的文件不存在,我们使用前几周的文件。所以需要旧周文件。

标签: python regex pandas dataframe glob


【解决方案1】:

如果您的文件总是有一个_ 来拆分,您可以创建一个字典,其中拆分值作为键,文件路径作为位置。

让我们使用 Python 3.4+ 中添加的 Pathlib,因为它更容易与文件系统一起使用。

正则表达式匹配文件名。

假设您的字典是如上创建的,其中文件名和路径作为我们可以执行此操作的值。您需要扩展该函数以处理多个文件匹配。

import re
from pathlib import path

file_dict = {file.stem : file for file in location.glob('*.xlsx')}

# assume the numbers are paths.
files = {'Zambia_W4.xlsm': 2,
 'Australia_W4.xlsx': 5,
 'France_W4.xlsx': 0,
 'Japan_W3.xlsm': 7,
 'India_W3.xlsx': 2,
 'Italy_W3.xlsx': 6,
 'MEA_W5.xlsx': 7,
 'NE_W5.xlsm': 4,
 'Russia_W5.xlsx': 3,
 'Spain_W2.xlsx': 5}

def file_name_match(file_dict,pattern):

    for name, source in file_dict.items():
        if re.search(pattern,name,flags=re.IGNORECASE):
            return file_dict.get(name)

file_name_match(file_dict,'italy')
output: 6

df = pd.read_excel(file_name_match(file_dict,'italy'),sheetname=...)

【讨论】:

  • 有没有办法在 read_excel 中使用正则表达式作为文件名?上述方法工作正常,但万一将来文件名发生变化,我不希望代码崩溃
  • @RSM 不在阅读的 excel 中,但在字典中,给我一些时间,我会编辑
  • 取决于你的追求。 glob 使用类似于 shell 的模式。阅读此page 了解更多信息。 glob 基于此模块。它确实有一个从正则表达式翻译的 fnmatch.translate 选项;但是,在 unix 样式模式中工作会更简单
【解决方案2】:

像这样简单地填充数据帧字典可能是可行的:

my_dfs = {}
for f in fls:
    my_dfs[f.split(“.”)[0]] = pandas.dataframe(f.split(“,”)[0], ...)

您也可以使用 for 循环来运行您需要为每个文件执行的作业,这不需要知道文件名。此外,也可以将所有电子表格读入一个 df,并确保每行都有一个具有相应文件名的附加列。

【讨论】:

    【解决方案3】:

    下面的代码假设每个国家/地区都有多个文件,并且需要对它们进行排序以找到最近的一周。

    import glob
    import os
    import re
    
    def find_country_file(country_name):
      all_country_files = glob.glob(os.path.join(inputs_path, '{0}_W*.*'))
      week_numbers = [re.search('W([0-9]+)', x) for x in all_country_files]
      week_numbers = [int(x.group(1)) for x in week_numbers if x is not None]
      latest_week_number = sorted(week_numbers, reversed=True)[0]
      latest_country_file = [x for x in all_country_files if 'W{0}.'.format(latest_week_number) in x]
      return os.path.basename(latest_country_file)
    
    
    df_italy = pd.read_excel(find_country_file('Italy') , sheet_name='Sheet1')
    df_russia = pd.read_excel(find_country_file('Russia'), sheet_name='Sheet3')
    df_france_1 = pd.read_excel(find_country_file('France'),sheet_name='Sheet1', usecols = 'M, Q', skiprows=4)
    df_spain = pd.read_excel(find_country_file('Spain'),sheet_name='Sheet2',usecols = 'T:U', skiprows=30 )
    df_ne = pd.read_excel(find_country_file('NE'),sheet_name='Sheet2',usecols = 'N,P', skiprows=4 )
    df_ne_c = pd.read_excel(find_country_file('NE'),sheet_name='Sheet1',usecols = 'H:J', skiprows=141)
    

    find_country 方法在路径中搜索所有带有国家名称的文件,使用正则表达式提取周数,对它们进行排序以找到最大的数字,然后从所有匹配的国家文件的 glob 中返回文件路径找到的最近一周。

    【讨论】:

      猜你喜欢
      • 2022-10-14
      • 2017-05-17
      • 2013-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多