【问题标题】:Pandas: split list in column into multiple rows [duplicate]熊猫:将列中的列表拆分为多行[重复]
【发布时间】:2018-10-17 11:34:05
【问题描述】:

我有一个关于将数据框列中的列表拆分为多行的问题。

假设我有这个数据框:

  Job position   Job type  id
0          [6]        [1]   3
1       [2, 6]  [3, 6, 5]   4
2          [1]        [9]  43

我想要数字的每一个组合,所以最终的结果是:

   id    Job position  Job type
0   3         6.0       1.0
1   4         2.0       3.0
2   4         2.0       6.0
3   4         2.0       5.0
4   4         6.0       3.0
5   4         6.0       6.0
6   4         6.0       5.0
7  43         1.0       9.0

因为现在我得到了这个结果:

   id    Job position  Job type
0   3         6.0       1.0
1   4         2.0       3.0
2   4         6.0       6.0
3   4         NaN       5.0
4  43         1.0       9.0

为了得到上面的结果,我做了:

df = df.set_index(['id'])
(df.apply(lambda x: pd.DataFrame(x.tolist(),index=x.index)
                        .stack()
                        .rename(x.name)).reset_index())

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    使用理解

    pd.DataFrame([
        [p, t, i] for P, T, i in df.values
        for p in P for t in T
    ], columns=df.columns)
    
       Job position  Job type  id
    0             6         1   3
    1             2         3   4
    2             2         6   4
    3             2         5   4
    4             6         3   4
    5             6         6   4
    6             6         5   4
    7             1         9  43
    

    迭代values的替代方法

    pd.DataFrame([
        [p, t, i] for P, T, i in df.itertuples(index=False)
        for p in P for t in T
    ], columns=df.columns)
    

    z = zip(df['Job position'], df['Job type'], df['id'])
    pd.DataFrame([
        [p, t, i] for P, T, i in z
        for p in P for t in T
    ], columns=df.columns)
    

    推广此解决方案以容纳任意数量的列

    pd.DataFrame([
        [p, t] + a for P, T, *a in df.values
        for p in P for t in T
    ], columns=df.columns)
    
       Job position  Job type  id
    0             6         1   3
    1             2         3   4
    2             2         6   4
    3             2         5   4
    4             6         3   4
    5             6         6   4
    6             6         5   4
    7             1         9  43
    

    【讨论】:

    • 非常不错
    • 感谢您的回答 piRSquared,效果很好,但是我想合并更多这样的列,那么您的方法可能有点棘手:)
    • 有办法适应它。但不用担心。如果我有时间,我会更新一个例子。
    • @MathiasLund 我已经更新了帖子。
    • 这是最简单优雅的方法,谢谢!
    【解决方案2】:

    类似于 Scott Boston 的建议,我建议您将列分开分解,然后将它们合并在一起。

    例如,对于“职位”:

    >>> df['Job position'].apply(pd.Series).reset_index().melt(id_vars='index').dropna()[['index', 'value']].set_index('index')
        value
    index   
    0   6.0
    1   2.0
    2   1.0
    1   6.0
    

    而且,一起来:

    df = pd.DataFrame({'Job position': [[6], [2, 6], [1]], 'Job type': [[1], [3, 6, 5], [9]], 'id': [3, 4, 43]})
    jobs = df['Job position'].apply(pd.Series).reset_index().melt(id_vars='index').dropna()[['index', 'value']].set_index('index')
    types = df['Job type'].apply(pd.Series).reset_index().melt(id_vars='index').dropna()[['index', 'value']].set_index('index')
    >>> pd.merge(
        pd.merge(
            jobs,
            types,
            left_index=True,
            right_index=True),
        df[['id']],
        left_index=True,
        right_index=True).rename(columns={'value_x': 'Job positions', 'value_y': 'Job type'})
    Job positions   Job type    id
    0   6.0 1.0 3
    1   2.0 3.0 4
    1   2.0 6.0 4
    1   2.0 5.0 4
    1   6.0 3.0 4
    1   6.0 6.0 4
    1   6.0 5.0 4
    2   1.0 9.0 43
    

    【讨论】:

      【解决方案3】:

      来自数据框构造函数

      s1=df.Jobposition.str.len()
      
      s2=df.Jobtype.str.len()
      pd.DataFrame({'id':df.id.repeat(s1*s2),
        'Jobposition':np.concatenate([np.repeat(x,y) for x,y in zip(df.Jobposition,s2)]),
        'Jobtype':np.concatenate(np.repeat(df.Jobtype,s1).values)})
      
         Jobposition  Jobtype  id
      0            6        1   3
      1            2        3   4
      1            2        6   4
      1            2        5   4
      1            6        3   4
      1            6        6   4
      1            6        5   4
      2            1        9  43
      

      【讨论】:

      • 非常不错
      • @AmiTavory 谢谢老兄:-)
      • 很好的回答 Wen,感谢您的贡献
      【解决方案4】:
      import itertools
      dfres = pd.DataFrame([j+(i[2],) for i in df.values for j in itertools.product(*i[0:2])]
              ,columns=df.columns)
      
         Job position  Job type  id
      0             6         1   3
      1             2         3   4
      2             2         6   4
      3             2         5   4
      4             6         3   4
      5             6         6   4
      6             6         5   4
      7             1         9  43
      

      【讨论】:

        猜你喜欢
        • 2019-12-28
        • 2018-07-26
        • 2019-11-26
        • 2018-11-16
        • 2016-08-30
        • 2021-08-13
        • 1970-01-01
        • 2018-10-09
        • 1970-01-01
        相关资源
        最近更新 更多