【问题标题】:Pandas - unflatten data frame with columns containing arrayPandas - 使用包含数组的列展平数据框
【发布时间】:2016-11-29 09:14:27
【问题描述】:

我有一个已在特定属性上展平的数据框:

id      property_a    properties_b
id_1    property_a_1  [property_b_11, property_b_12]
id_2    property_a_2  [property_b_21, property_b_22, property_b_23]

..................

我想扩展properties_b 列以返回到如下所示的数据框:

id      property_a    property_b
id_1    property_a_1  property_b_11
id_1    property_a_1  property_b_12
id_2    property_a_2  property_b_21
id_2    property_a_2  property_b_22
id_2    property_a_2  property_b_23

..................

我怀疑这对 Pandas 来说非常简单,但作为 Python 新手,我很难找到一种优雅的方式来做到这一点。

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    这是使用to_records、一些元组映射和from_records 的另一种方法。

    import pandas as pd
    import itertools
    
    def expand_column(df, col_id):
        records = map(lambda r: [r[1:col_id] + (l,) + r[col_id + 1:] for l in r[col_id]], map(tuple, df.to_records()))
        return pd.DataFrame.from_records(itertools.chain.from_iterable(records), columns=df.columns)
    
    df = pd.DataFrame([['a', [1,2,3], 'a'],['b', [4,5], 'b']], columns=['C1', 'L', 'C2'])
    
    print(df)
    print(expand_column(df, 2))
    
    #   C1          L C2
    # 0  a  [1, 2, 3]  a
    # 1  b     [4, 5]  b
    #
    #   C1  L C2
    # 0  a  1  a
    # 1  a  2  a
    # 2  a  3  a
    # 3  b  4  b
    # 4  b  5  b
    

    【讨论】:

      【解决方案2】:

      herehere 已解决此问题。如果您觉得这些问题和答案有用,也请随时为它们投票。

      设置

      df = pd.DataFrame([
              ['id_1', 'property_a_1', ['property_b_11', 'property_b_12']],
              ['id_2', 'property_a_2', ['property_b_21', 'property_b_22', 'property_b_23']],
          ], columns=['id', 'property_a', 'properties_b'])
      
      df
      

      rows = []
      for i, row in df.iterrows():
          for a in row.properties_b:
              row.properties_b = a
              rows.append(row)
      
      pd.DataFrame(rows, columns=df.columns)
      

      方便的功能

      def loc_expand(df, loc):
          rows = []
          for i, row in df.iterrows():
              vs = row.at[loc]
              new = row.copy()
              for v in vs:
                  new.at[loc] = v
                  rows.append(new)
      
          return pd.DataFrame(rows)
      
      def iloc_expand(df, iloc):
          rows = []
          for i, row in df.iterrows():
              vs = row.iat[iloc]
              new = row.copy()
              for v in vs:
                  row.iat[iloc] = v
                  rows.append(row)
      
          return pd.DataFrame(rows)
      

      这些都应该返回与上面相同的结果。

      loc_expand(df, 'properties_b')
      iloc_expand(df, 2)
      

      【讨论】:

      • 感谢您的解决方案:)。不过,它需要做一个小改动才能完全工作:在第一个循环中,您正在编辑行而不先克隆它。在方便的函数中,copy() 调用应该在内部循环中完成 ` def loc_expand(df, loc): rows = [] for i, row in df.iterrows(): vs = row.at[loc] for v在 vs: new = row.copy() new.at[loc] = v rows.append(new) return pd.DataFrame(rows) `
      猜你喜欢
      • 2019-10-24
      • 2016-03-16
      • 1970-01-01
      • 1970-01-01
      • 2020-09-28
      • 2018-03-28
      • 1970-01-01
      • 2014-10-15
      • 1970-01-01
      相关资源
      最近更新 更多