【问题标题】:"unstack" a pandas column containing lists into multiple rows [duplicate]将包含列表的pandas列“取消堆叠”成多行[重复]
【发布时间】:2017-06-20 02:39:43
【问题描述】:

假设我有以下 Pandas 数据框:

df = pd.DataFrame({"a" : [1,2,3], "b" : [[1,2],[2,3,4],[5]]})
   a          b
0  1     [1, 2]
1  2  [2, 3, 4]
2  3        [5]

我将如何“取消堆叠”“b”列中的列表以将其转换为数据框:

   a  b
0  1  1
1  1  2
2  2  2
3  2  3
4  2  4
5  3  5

【问题讨论】:

    标签: python list pandas dataframe


    【解决方案1】:

    更新: 通用矢量化方法 - 也适用于多列 DF:

    假设我们有以下 DF:

    In [159]: df
    Out[159]:
       a          b  c
    0  1     [1, 2]  5
    1  2  [2, 3, 4]  6
    2  3        [5]  7
    

    解决方案:

    In [160]: lst_col = 'b'
    
    In [161]: pd.DataFrame({
         ...:     col:np.repeat(df[col].values, df[lst_col].str.len())
         ...:     for col in df.columns.difference([lst_col])
         ...: }).assign(**{lst_col:np.concatenate(df[lst_col].values)})[df.columns.tolist()]
         ...:
    Out[161]:
       a  b  c
    0  1  1  5
    1  1  2  5
    2  2  2  6
    3  2  3  6
    4  2  4  6
    5  3  5  7
    

    设置:

    df = pd.DataFrame({
        "a" : [1,2,3],
        "b" : [[1,2],[2,3,4],[5]],
        "c" : [5,6,7]
    })
    

    矢量化 NumPy 方法:

    In [124]: pd.DataFrame({'a':np.repeat(df.a.values, df.b.str.len()),
                            'b':np.concatenate(df.b.values)})
    Out[124]:
       a  b
    0  1  1
    1  1  2
    2  2  2
    3  2  3
    4  2  4
    5  3  5
    

    旧答案:

    试试这个:

    In [89]: df.set_index('a', append=True).b.apply(pd.Series).stack().reset_index(level=[0, 2], drop=True).reset_index()
    Out[89]:
       a    0
    0  1  1.0
    1  1  2.0
    2  2  2.0
    3  2  3.0
    4  2  4.0
    5  3  5.0
    

    或者更好的解决方案provided by @Boud:

    In [110]: df.set_index('a').b.apply(pd.Series).stack().reset_index(level=-1, drop=True).astype(int).reset_index()
    Out[110]:
       a  0
    0  1  1
    1  1  2
    2  2  2
    3  2  3
    4  2  4
    5  3  5
    

    【讨论】:

    • 嗯,然后删除追加和删除级别-1?
    • 我希望这是 Pandas 的一部分。
    • @AmiTavory,谢谢!有a bit more generic version,但还没有经过足够的测试,无法将其推送到 Pandas、IMO...
    • 因为我 s̶t̶e̶a̶l̶ 使用 MaxU 的另一个答案......我想知道他让我赚了多少钱。感谢一直以来的支持!
    • 简单一班:df.explode('b')
    【解决方案2】:

    这是itertuples 的另一种方法-

    df = pd.DataFrame({"a" : [1,2,3], "b" : [[1,2],[2,3,4],[5]]})
    
    data = []
    
    for i in df.itertuples():
        lst = i[2]
        for col2 in lst:
            data.append([i[1], col2])
    
    df_output = pd.DataFrame(data =data, columns=df.columns)
    df_output 
    

    输出是 -

            a   b
        0   1   1
        1   1   2
        2   2   2
        3   2   3
        4   2   4
        5   3   5
    

    编辑:您还可以将循环压缩为单个代码并将data 填充为 -

    data = [[i[1], col2] for i in df.itertuples() for col2 in i[2]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-14
      • 2016-01-02
      • 2013-04-01
      • 2016-02-27
      • 2020-01-02
      • 1970-01-01
      相关资源
      最近更新 更多