pandas Python Dataframe找到文件类型,选择正确的pd.read_并合并它们

qlvxas9a  于 2022-12-02  发布在  Python
关注(0)|答案(3)|浏览(121)

我有一个要导入到数据框中的文件列表
信用证号码:

# list contains the dataset name followed by the column name to match all the datasets; this list keeps changing and even the file formats. These dataset file names are provided by the user, and they are unique. 
# First: find the file extension format and select appropriate pd.read_ to import
# second: merge the dataframes on the index

# in the below list, 
file_list = ['dataset1.csv','datetime','dataset2.xlsx','timestamp']

df = pd.DataFrame()
for i in range(0:2:len(file_list)):
   # find the file type first
   # presently, I don't know how to find the file type; so 
   file_type = 'csv'
   # second: merge the dataframe into the existing dataframe on the index
   tdf = pd.DataFrame()
   if file_type == 'csv': 
       tdf = pd.read_csv('%s'%(file_list[i])))
   if file_type == 'xlsx': 
       tdf = pd.read_excel('%s'%(file_list[i])))
   tdf.set_index('%s'%(file_list[i+1]),inplace=True)
   # Merge dataframe with the existing dataframe
   df = df.merge(tdf,right_index=True,left_index=True)

我已经到了这里。有任何直接模块可以找到文件类型吗?我找到了magic,但导入时出现了问题。另外,建议一个更好的方法来合并文件吗?更新:工作解决方案从下面的@ljdyer回答中得到启发,我得到了下面的答案,这是完美的工作:

def find_file_type_import(file_name):
    # Total file extensions possible for importing data
    file_type = {'csv':'pd.read_csv(file_name)',
                  'xlsx':'pd.read_excel(file_name)',
                 'txt':'pd.read_csv(file_name)',
                 'parquet':'pd.read_parquet(file_name)',
                  'json':'pd.read_json(file_name)'
                 }
    df = [eval(val) for key,val in file_type.items() if file_name
          .endswith(key)][0]
    return df
  df = find_file_type_import(file_list [0])

这是完美的工作。感谢您的宝贵建议。另外,纠正我与使用eval是好的一个或不?

r1zhe5dt

r1zhe5dt1#

文件类型只是文件名末尾的三个或四个字母,因此最简单的方法是:

if file_list[i].endswith('csv'):

等等。
其他公共选项可以是os.path.splitextPath对象的suffix属性(分别来自内置的ospathlib库)。
合并的方式看起来不错,但我不知道为什么要对read_set_index等参数使用百分比表示法。列表中的元素只是字符串,例如

tdf = pd.read_csv('%s'%(file_list[i])))

可能只是:

tdf = pd.read_csv(file_list[i])

(对后续问题的答复)

使用dict真是个好主意!通常认为尽可能避免使用eval是一个好习惯,所以这里有一个替代选项,panda函数本身作为字典值。我还建议使用一个更漂亮的语法来理解列表,只有一个元素基于this answer,还有一些更清晰的变量名:

def find_file_type_import(file_name):
    # Total file extensions possible for importing data
    read_functions = {'csv': pd.read_csv,
                    'xlsx': pd.read_excel,
                    'txt': pd.read_csv,
                    'parquet': pd.read_parquet,
                    'json': pd.read_json}
    [df] = [read(file_name) for file_ext, read in read_functions.items()
        if file_name.endswith(file_ext)]
    return df
j0pj023g

j0pj023g2#

你可以使用glob(或者仅仅使用os)来从文件名的一部分中检索文件列表。因为你保证了文件的唯一性,而不管扩展名是什么,所以它只能是一个(否则就用一个循环来遍历检索到的元素)。
一旦你有了完整的文件名(它显然有扩展名),只需执行一个split(),获取对应于文件扩展名的最后一个元素。
然后,您可以使用适当的函数读取 Dataframe 。
下面是一个代码示例:

from glob import glob

file_list = [
    'dataset0',  # corresponds to dataset0.csv
    'dataset1',  # corresponds to dataset1.xlsx
    'dataset2.a'
]

for file in file_list:
    files_with_curr_name = glob(f'*{file}*')

    if len(files_with_curr_name) > 0:
        full_file_name = files_with_curr_name[0]  # take the first element, the uniqueness of the file name being guaranteed

        # extract the file extension (string after the dot, so the last element of split)
        file_type = full_file_name.split(".")[-1]

        if file_type == 'csv':
            print(f'Read {full_file_name} as csv')
            # df = pd.read_csv(full_file_name)
        elif file_type == 'xlsx':
            print(f'Read {full_file_name} as xlsx')
        else:
            print(f"Don't read {full_file_name}")

输出将为:

Read dataset0.csv as csv
Read dataset1.xlsx as xlsx
Don't read dataset2.a
anauzrmj

anauzrmj3#

使用pathlib和一个switch dict来调用函数。

from pathlib import Path

import pandas as pd

def main(files: list) -> None:
    caller = {
        ".csv": read_csv,
        ".xlsx": read_excel,
        ".pkl": read_pickle
    }

    for file in get_path(files):
        print(caller.get(file.suffix)(file))

def get_path(files: list) -> list:
    file_path = [x for x in Path.home().rglob("*") if x.is_file()]

    return [x for x in file_path if x.name in files]

def read_csv(file: Path) -> pd.DataFrame:
    return pd.read_csv(file)

def read_excel(file: Path) -> pd.DataFrame:
    return pd.read_excel(file)

def read_pickle(file: Path) -> pd.DataFrame:
    return pd.read_pickle(file)

if __name__ == "__main__":
    files_to_read = ["spam.csv", "ham.pkl", "eggs.xlsx"]
    main(files_to_read)

相关问题