如何将数据框单元格中的列表分解为单独的行

2024-06-02 10:36:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我希望将包含列表的pandas单元格转换为这些值的行。

所以,拿着这个:

enter image description here

如果我想解包并堆叠nearest_neighbors列中的值,以便每个值都是每个opponent索引中的一行,那么我最好如何进行呢?有没有熊猫的方法是为了这样的操作?


Tags: 方法pandas列表neighborsnearestopponent
3条回答

在下面的代码中,我首先重置索引以使行迭代更容易。

我创建一个列表列表,其中外部列表的每个元素是目标数据帧的一行,而内部列表的每个元素是其中一列。这个嵌套列表最终将被连接起来以创建所需的数据帧。

我使用lambda函数和列表迭代为nearest_neighbors的每个元素创建一行,并与相关的nameopponent配对。

最后,我从这个列表创建一个新的数据帧(使用原始列名并将索引设置回nameopponent)。

df = (pd.DataFrame({'name': ['A.J. Price'] * 3, 
                    'opponent': ['76ers', 'blazers', 'bobcats'], 
                    'nearest_neighbors': [['Zach LaVine', 'Jeremy Lin', 'Nate Robinson', 'Isaia']] * 3})
      .set_index(['name', 'opponent']))

>>> df
                                                    nearest_neighbors
name       opponent                                                  
A.J. Price 76ers     [Zach LaVine, Jeremy Lin, Nate Robinson, Isaia]
           blazers   [Zach LaVine, Jeremy Lin, Nate Robinson, Isaia]
           bobcats   [Zach LaVine, Jeremy Lin, Nate Robinson, Isaia]

df.reset_index(inplace=True)
rows = []
_ = df.apply(lambda row: [rows.append([row['name'], row['opponent'], nn]) 
                         for nn in row.nearest_neighbors], axis=1)
df_new = pd.DataFrame(rows, columns=df.columns).set_index(['name', 'opponent'])

>>> df_new
                    nearest_neighbors
name       opponent                  
A.J. Price 76ers          Zach LaVine
           76ers           Jeremy Lin
           76ers        Nate Robinson
           76ers                Isaia
           blazers        Zach LaVine
           blazers         Jeremy Lin
           blazers      Nate Robinson
           blazers              Isaia
           bobcats        Zach LaVine
           bobcats         Jeremy Lin
           bobcats      Nate Robinson
           bobcats              Isaia

编辑2017年6月

另一种方法如下:

>>> (pd.melt(df.nearest_neighbors.apply(pd.Series).reset_index(), 
             id_vars=['name', 'opponent'],
             value_name='nearest_neighbors')
     .set_index(['name', 'opponent'])
     .drop('variable', axis=1)
     .dropna()
     .sort_index()
     )

我认为这是一个非常好的问题,在Hive中,您将使用EXPLODE,我认为有一个案例需要说明,Pandas默认情况下应该包含此功能。我可能会用这样的嵌套生成器来分解列表列:

pd.DataFrame({
    "name": i[0],
    "opponent": i[1],
    "nearest_neighbor": neighbour
    }
    for i, row in df.iterrows() for neighbour in row.nearest_neighbors
    ).set_index(["name", "opponent"])

使用apply(pd.Series)stack,然后使用reset_indexto_frame

In [1803]: (df.nearest_neighbors.apply(pd.Series)
              .stack()
              .reset_index(level=2, drop=True)
              .to_frame('nearest_neighbors'))
Out[1803]:
                    nearest_neighbors
name       opponent
A.J. Price 76ers          Zach LaVine
           76ers           Jeremy Lin
           76ers        Nate Robinson
           76ers                Isaia
           blazers        Zach LaVine
           blazers         Jeremy Lin
           blazers      Nate Robinson
           blazers              Isaia
           bobcats        Zach LaVine
           bobcats         Jeremy Lin
           bobcats      Nate Robinson
           bobcats              Isaia

细节

In [1804]: df
Out[1804]:
                                                   nearest_neighbors
name       opponent
A.J. Price 76ers     [Zach LaVine, Jeremy Lin, Nate Robinson, Isaia]
           blazers   [Zach LaVine, Jeremy Lin, Nate Robinson, Isaia]
           bobcats   [Zach LaVine, Jeremy Lin, Nate Robinson, Isaia]

相关问题 更多 >