【问题标题】:Reading in a list of files into a list of DataFrames将文件列表读入 DataFrame 列表
【发布时间】:2016-07-02 23:31:02
【问题描述】:

我正在尝试将文件列表读入 Python 中的 Pandas DataFrames 列表。但是,下面的代码不起作用。

files = [file1, file2, file3]

df1 = pd.DataFrame()
df2 = pd.DataFrame()
df3 = pd.DataFrame()

dfs = [df1, df2, df3]

# Read in data files
for file,df in zip(files, dfs):
    if file_exists(file):
        with open(file, 'rb') as in_file:
            df = pd.read_csv(in_file, low_memory=False)
            print df        #the file is getting read properly

print df1    #empty
print df2    #empty
print df3    #empty

如果我将原始 DataFrames 作为 DataFrames 列表传递到 for 循环中,如何更新它们?

【问题讨论】:

  • 您将这些文件读入三个 DF 或将它们合并为一个 DF 的目标是什么?
  • 您正在更新可迭代对象,而不是元素是什么,如果您迭代列表,这将是同样的事情。您是否有理由需要预先构建空的 dfs 而不是仅设置 dfs=[] 然后遍历文件并执行 dfs.append(pd.read_csv(in_file)
  • 当你遍历一个列表时,你不能直接修改元素。 df = pd.read_csv(in_file, low_memory=False) 行实际上并没有修改列表中的元素,它正在修改元素的副本。编辑:击败我@EdChum :)
  • 请参阅stackoverflow.com/questions/1207406/… 以获得解释,但基本上您可以跳过此步骤,只需将其附加到您创建的 dfs 列表中
  • @MaxU:我试图将文件读入三个不同的 DF。这个想法是,通过使用循环,可以简洁地导入任意数量的文件。

标签: python list pandas dataframe


【解决方案1】:

试试这个:

dfs = [pd.read_csv(f, low_memory=False) for f in files]

如果要检查文件是否存在:

import os

dfs = [pd.read_csv(f, low_memory=False) for f in files if os.path.isfile(f)]

如果你想将它们全部连接到一个数据框中:

df = pd.concat([pd.read_csv(f, low_memory=False)
                for f in files if os.path.isfile(f)],
               ignore_index=True)

【讨论】:

    【解决方案2】:

    在迭代列表元素时,您并没有在处理列表元素本身,但是您没有在列表上进行操作。

    您需要将元素插入(或附加)到列表中。一种可能是:

    files = [file1, file2, file3]
    
    dfs = [None] * 3 # Just a placeholder
    
    # Read in data files
    for i, file in enumerate(files): # Enumeration instead of zip
        if file_exists(file):
            with open(file, 'rb') as in_file:
                dfs[i] = pd.read_csv(in_file, low_memory=False) # Setting the list element
                print dfs[i]      #the file is getting read properly
    

    这会更新列表元素并且应该可以工作。

    【讨论】:

      【解决方案3】:

      您的代码似乎过于复杂,您可以这样做:

      files = [file1, file2, file3]
      
      dfs = []
      
      # Read in data files
      for file in files:
          if file_exists(file):
              dfs.append(pd.read_csv(file, low_memory=False))
      

      您最终会得到一个所需的 dfs 列表

      【讨论】:

        【解决方案4】:

        你可以试试list理解:

        files = [file1, file2, file3]
        
        dfs = [pd.read_csv(x, low_memory=False) for x in files if file_exists(x)]
        

        【讨论】:

          【解决方案5】:

          自定义编写的 Python 函数,可适当处理 CSV 和 JSON 文件。

          def generate_list_of_dfs(incoming_files):
              """
              Accepts a list of csv and json file/path names.
              Returns a list of DataFrames.
              """
              outgoing_files = []
              for filename in incoming_files:
                  file_extension = filename.split('.')[1]
                  if file_extension == 'json':
                      with open(filename, mode='r') as incoming_file:
                          outgoing_json = pd.DataFrame(json.load(incoming_file))
                          outgoing_files.append(outgoing_json)
                  if file_extension == 'csv':
                      outgoing_csv = pd.read_csv(filename)
                      outgoing_files.append(outgoing_csv)
              return outgoing_files
          

          如何调用这个函数

          import pandas as pd
          import json    
          files_to_be_read = ['filename1.json', 'filename2.csv', 'filename3.json', 'filename4.csv']
          dataframes_list = generate_list_of_dfs(files_to_be_read)
          

          【讨论】:

            【解决方案6】:

            这是一个简单的解决方案,如果您不需要列表中的所有数据框,则可以避免使用列表来保存所有数据框。

            import fnmatch
            
            # get the CSV files only
            files = fnmatch.filter(os.listdir('.'), '*.csv')
            files
            

            现在是名称列表的输出:

            ['Feedback Form Submissions 1.21-1.25.22.csv',
             'Feedback Form Submissions 1.21.22.csv',
             'Feedback Form Submissions 1.25-1.31.22.csv']
            

            现在创建一个简单的新名称列表,以便更轻松地使用它们:

            # use a simple format
            names = []
            for i in range(0,len(files)):
                names.append('data' + str(i))
            names
            
            ['data0', 'data1', 'data2']
            

            您可以使用任何您想要的名称列表。下一步获取文件名和名称列表,然后将它们分配给名称。

            # i is the incrementor for the list of names
            i = 0
            
            # iterate through the file names
            for file in files:
                # make an empty dataframe
                df = pd.DataFrame()
                # load the first file in
                df = pd.read_csv(file, low_memory=False)
                # get the first name from the list, this will be a string
                new_name = names[i]
                # assign the string to the variable and assign it to the dataframe 
                locals()[new_name] = df.copy()
                # increment the list of names
                i = i + 1
            

            你现在有 3 个独立的数据框,分别命名为 data0、data1、data2,并执行类似的命令

            data2.info()
            

            【讨论】:

              猜你喜欢
              • 2015-05-14
              • 1970-01-01
              • 2017-11-08
              • 1970-01-01
              • 1970-01-01
              • 2015-12-13
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多