【问题标题】:Looping over a list of dictionaries with DataFrames使用 DataFrame 循环遍历字典列表
【发布时间】:2020-11-07 05:21:33
【问题描述】:

我有一个列表,其中的输入文件存储为代表导入的 Excel 文件的字典。每个字典都有多个存储为 DataFrames 的工作表。

当三个 NaN 值出现在列中时,我想存储彼此附加的不同字典(Excel 文件)的相同键(工作表),同时打破工作表。我初始化了一个新字典,它应该具有与字典(Excel 文件)相同的键(表),但现在所有数据都附加到这个字典 d_sheets

为此,我使用以下代码:

input_files = []
for file in read_input:
    input_file = pd.read_excel(io=file, sheet_name=needed_sheets, dtype=str)
    input_files.append(input_file)

d_sheets = {}
for dictionary in input_files:
      for sheet_name in sorted(dictionary):
            d_sheets[sheet_name] = pd.DataFrame()
            if sheet_name != 'Sheetname1':
                cell = dictionary[sheet_name]['Columnname1']
            else:
                cell = dictionary[sheet_name]['Columnname2']
            three_NaNs = cell.isna() & cell.shift(-1).isna() & cell.shift(-2).isna()
            first_instance = cell[three_NaNs].index.min()
            good_data = dictionary[sheet_name][cell.index <= first_instance]
            d_sheets[sheet_name].append(good_data)
            d_sheets[sheet_name] = pd.concat([d_sheets[sheet_name], good_data], axis=0)

看来,对于单个字典(Excel 文件),布尔语句完成了它们的工作,并且密钥存储在 d_sheets 中。但是,我找不到循环遍历 input_files 中的字典的工作方法。

什么可能导致我无法遍历列表input_files 的项目并将所有工作表存储在d_sheets 中的问题?

【问题讨论】:

    标签: python excel pandas dictionary


    【解决方案1】:

    我已经解决了这个问题,因为 DataFrame 初始化不应该在 d_sheets[sheet_name] = pd.DataFrame() 的 for 循环内。这样,循环的每次迭代都会清除 DataFrame,然后执行计算。最后,这会导致最新的 Excel 文件仅作为输出,而不是所有文件合并。

    【讨论】:

      【解决方案2】:

      如果我正确理解了您的“碎纸”策略(如果我不理解,请原谅我)这里有一个脚本可以完成这项工作:

      import pandas as pd
      
      # helper function to break sheets with 3 consecutive NaN in any column
      def df_breaker(df):
          res = pd.DataFrame()
          nan_ind = pd.DataFrame({k:[0] for k in df.columns})
          for row in df.iloc:
              nan_ind=(row.isna()*nan_ind)+row.isna()
              if (nan_ind.iloc[0]>=3).any():
                  return res.iloc[:-2]
              res=res.append(row)
          return res
      
      # shall be broken after second row
      dfa = pd.DataFrame({'c1':[0,1,None,None,None],'c2':[5,6,7,8,9]})
      # shall not be broken 
      dfb = pd.DataFrame({'c1':[10,None,12,None,14],'c2':[None,16,None,18,19]})
      # shall not be broken 
      dfc = pd.DataFrame({'c1':[20,21,22,23,24],'c2':[25,26,27,28,29]})
      # shall not be broken 
      dfd = pd.DataFrame({'c1':[30,31,32,33,34],'c2':[35,36,37,38,39]})
      
      input_files = [{'sheet1':dfa, 'sheet2':dfb},{'sheet1':dfc, 'sheet2':dfd}]
      
      
      d_sheets ={}
      for key in input_files[0]:
          d_sheets[key]=pd.concat([df_breaker(k[key]) for k in input_files])
      

      【讨论】:

      • 您好 Gillu,感谢您提供的出色功能正是我所需要的。但是,在我的脚本中,该函数不会遍历字典列表,而是使用单个 Excel 文件。你能帮我指出我们的名单之间的差异吗?我的列表是使用带有 pd.read_excel 函数的 for 循环创建的
      • 我已经在代码中添加了 input_files 列表。这是否说明了为什么对列表项的循环不起作用?
      猜你喜欢
      • 1970-01-01
      • 2014-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-11
      • 2016-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多