【问题标题】:Print non-empty dataframes only from list comprehension仅从列表理解中打印非空数据帧
【发布时间】:2017-01-28 22:00:42
【问题描述】:

目前我有一个通过列表理解运行的数据框列表。结果是所有具有或不具有在列表理解中限定函数的行的数据帧。我只想打印出非空的df。这有可能吗?另外,是否也可以打印出数据框的名称?

例子:

N = 5

np.random.seed(0)

df1 = pd.DataFrame(
    {'X':np.random.uniform(0,5,N),
     'Y':np.random.uniform(0,5,N),
     'Z':np.random.uniform(0,5,N),
    })

df2 = pd.DataFrame(
    {'X':np.random.uniform(-5,0,N),
     'Y':np.random.uniform(-5,0,N),
     'Z':np.random.uniform(-5,0,N),
    })

def func_sel(df):
    return df[df['X'] > 0]

dfs_list = [df1, df2]

dfs_sel = [func_sel(x) for x in dfs_list]

dfs_sel

Out[14]:
[          X         Y         Z
 0  2.744068  3.229471  3.958625
 1  3.575947  2.187936  2.644475
 2  3.013817  4.458865  2.840223
 3  2.724416  4.818314  4.627983
 4  2.118274  1.917208  0.355180, Empty DataFrame
 Columns: [X, Y, Z]
 Index: []]

编辑: 我在这里需要的是 df1 仅以“df1”作为某种标签显示。

【问题讨论】:

  • 你在dfs_sel = [func_sel(x) for x in dfs_list if len(x)]之后吗?
  • 我已经进行了编辑。

标签: python pandas numpy


【解决方案1】:
  • 我同意@MaxU,如果你想要dfs 的名字,你需要将名字嵌入到数据结构中。为此,我将使用一个元组列表。
  • 我将使用empty 属性来过滤列表

dfs_list = [('df1', df1), ('df2', df2)]
dfs_sel = [
    (n, df) for n, df in [(n, func_sel(x)) for n, x in dfs_list] if not df.empty]

dfs_sel

[('df1',           X         Y         Z
  0  2.744068  3.229471  3.958625
  1  3.575947  2.187936  2.644475
  2  3.013817  4.458865  2.840223
  3  2.724416  4.818314  4.627983
  4  2.118274  1.917208  0.355180)]

【讨论】:

    【解决方案2】:

    在这种情况下,我会使用字典而不是列表。

    演示:

    In [110]: dfs_dict = {'df1':df1, 'df2':df2}
    
    In [111]: dfs_sel = {name:func_sel(df) for name, df in dfs_dict.items()}
    
    In [112]: dfs_sel
    Out[112]:
    {'df1':           X         Y         Z
     0  2.744068  3.229471  3.958625
     1  3.575947  2.187936  2.644475
     2  3.013817  4.458865  2.840223
     3  2.724416  4.818314  4.627983
     4  2.118274  1.917208  0.355180, 'df2': Empty DataFrame
     Columns: [X, Y, Z]
     Index: []}
    
    In [113]: [df if len(df) else name for name, df in dfs_sel.items()]
    Out[113]:
    ['df2',           X         Y         Z
     0  2.744068  3.229471  3.958625
     1  3.575947  2.187936  2.644475
     2  3.013817  4.458865  2.840223
     3  2.724416  4.818314  4.627983
     4  2.118274  1.917208  0.355180]
    

    【讨论】:

      【解决方案3】:

      这个怎么样:

      编辑:此版本支持手动命名 DataFrame 或自动枚举。

      import pandas as pd
      import numpy as np
      
      N = 5
      
      np.random.seed(0)
      
      df1 = pd.DataFrame(
          {'X':np.random.uniform(0,5,N),
           'Y':np.random.uniform(0,5,N),
           'Z':np.random.uniform(0,5,N),
          })
      
      
      df2 = pd.DataFrame(
          {'X':np.random.uniform(-5,0,N),
           'Y':np.random.uniform(-5,0,N),
           'Z':np.random.uniform(-5,0,N),
          })
      
      # OPTIONAL: manually assign names
      df1.name = 'df1'
      df2.name = 'df2'
      
      def func_sel(df, name=None):
          rdf = df[df['X'] > 0]
          try:
              rdf.name = df.name
          except:
              rdf.name = name
          rdf.columns = ['%s %s' % (rdf.name or '', c) for c in rdf.columns]
          return rdf
      
      dfs_list = [df1, df2]
      
      dfs_sel = [func_sel(df, 'df%d' % (x+1)) for x, df in enumerate(dfs_list) if not func_sel(df).empty]
      
      dfs_sel
      

      dfs_sel 输出:

      [      df1 X     df1 Y     df1 Z
      0  2.744068  3.229471  3.958625
      1  3.575947  2.187936  2.644475
      2  3.013817  4.458865  2.840223
      3  2.724416  4.818314  4.627983
      4  2.118274  1.917208  0.355180]
      

      每一列都附加了 DataFrame 的名称。如果没有手动分配名称,将使用枚举。

      【讨论】:

      • 但是请注意,pandas.DataFrame 对象不会保留任意元数据属性,例如 name 属性,如果您在将 DataFrame 传递给 func_sel 函数之前对其执行任何操作.见here
      • 这适用于提供的示例,但请注意。如果他们需要对 DataFrame 执行进一步的操作,也许名称应该存储在其他地方或提供给 func_sel,具体取决于 OP 的需要。
      • @AArias,谢谢。但是有一个问题,我必须将此名称属性添加到我拥有的所有 df 中,准确地说是 81。我想这必须手动完成?
      • @Zanshin 不,刚刚更新了答案,这样您就不必手动指定名称了。
      • @Zanshin 我刚刚再次更新了答案。此最终版本支持手动为 dfs 分配名称和自动枚举。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-14
      • 2013-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多