【问题标题】:How to transform list of variable length from one python dataframe column into rows?如何将可变长度列表从一个 python 数据框列转换为行?
【发布时间】:2021-10-07 04:45:00
【问题描述】:

我正在尝试将列表从一个数据框列转换为行,但不确定如何在 python 中有效地做到这一点? 我的实际数据有数千行和可变长度列表(在Specs 列中,但为了简化,我将使用下面的示例。

import pandas as pd
data = [{'Type': 'A', 'Specs': [['a1', 50], ['a2', 14]]},
   {'Type': 'B', 'Specs': [['b1', 20], ['b2', 25], ['b3', 15], ['b4', 10]]},
   {'Type': 'C', 'Specs': [['c1', 32]]} ]
df = pd.DataFrame(data)

最终的结果应该和下面数据框的输出等价

data_out= [{'Type': 'A', 'model':'a1', 'qty': 50},
   {'Type': 'A', 'model':'a2', 'qty': 14},
   {'Type': 'B', 'model':'b1', 'qty': 20},
   {'Type': 'B', 'model':'b2', 'qty': 25},
   {'Type': 'B', 'model':'b3', 'qty': 15},
   {'Type': 'B', 'model':'b4', 'qty': 10},
   {'Type': 'C', 'model':'c1', 'qty': 32}]
df_out = pd.DataFrame(data_out)

我尝试将apply 与将每个行列表/值转换为数据框的函数一起使用,并且对如何为每行返回数据框并使用新行扩展新数据框感到困惑。如果我走错了路,请告诉我,在大数据上获得所需数据帧输出的最有效方法是什么?谢谢

def convert_list(my_list):
   my_df = pd.DataFrame(pv_list, columns=['model', 'qty'])
return my_df

df[['model', 'qty']] = df['Specs'].apply(convert_list)

【问题讨论】:

    标签: python pandas list dataframe


    【解决方案1】:

    您不必编写任何自定义函数或加入/合并,使用explode

    文档:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.explode.html

    import pandas as pd
    data = [{'Type': 'A', 'Specs': [['a1', 50], ['a2', 14]]},
       {'Type': 'B', 'Specs': [['b1', 20], ['b2', 25], ['b3', 15], ['b4', 10]]},
       {'Type': 'C', 'Specs': [['c1', 32]]} ]
    df = pd.DataFrame(data)
    
    # Code Example
    df=df.explode('Specs').reset_index(drop=True)
    df[['model','qty']] =  pd.DataFrame(df["Specs"].to_list())
    df.drop('Specs', axis=1, inplace=True)
    df
    
    |    | Type   | model   |   qty |
    |---:|:-------|:--------|------:|
    |  0 | A      | a1      |    50 |
    |  1 | A      | a2      |    14 |
    |  2 | B      | b1      |    20 |
    |  3 | B      | b2      |    25 |
    |  4 | B      | b3      |    15 |
    |  5 | B      | b4      |    10 |
    |  6 | C      | c1      |    32 |
    

    PS: 就是这样,如果它仍然很慢,我建议你看看并行化的东西!

    【讨论】:

    • 您的代码示例已经足够快了,所以我至少现在不需要研究并行过程。谢谢
    【解决方案2】:

    在你的情况下尝试

    s = df.pop('Specs').explode()
    pd.DataFrame(s.tolist(),columns=['Model','Qty'],index=s.index).join(df)
    Out[84]: 
      Model  Qty Type
    0    a1   50    A
    0    a2   14    A
    1    b1   20    B
    1    b2   25    B
    1    b3   15    B
    1    b4   10    B
    2    c1   32    C
    

    【讨论】:

      【解决方案3】:

      你可以使用explode()+join()+DataFrame()+pop():

      df=df.explode('Specs',ignore_index=True)
      df[['Model','Qty']]=pd.DataFrame(df.pop('Specs').tolist())
      #OR
      #df=df.join(pd.DataFrame(df.pop('Specs').tolist(),columns=['Model','Qty']))
      

      explode()+drop()+.str访问者:

      df=df.explode('Specs',ignore_index=True)
      df['Model']=df['Specs'].str[0]
      df['Qty']=df['Specs'].str[1]
      df=df.drop('Specs',1)
      

      explode()+pop()+agg():

      df=df.explode('Specs',ignore_index=True)
      df[['Model','Qty']]=df.pop('Specs').agg(pd.Series)
      

      df 的输出:

         Type     Model   Qty
      0   A       a1      50
      1   A       a2      14
      2   B       b1      20
      3   B       b2      25
      4   B       b3      15
      5   B       b4      10
      6   C       c1      32
      

      【讨论】:

        猜你喜欢
        • 2013-09-30
        • 2020-02-13
        • 1970-01-01
        • 2016-10-15
        • 1970-01-01
        • 1970-01-01
        • 2016-02-05
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多