首页 >后端开发 >Python教程 >如何取消 Pandas DataFrame 中包含列表的列的嵌套?

如何取消 Pandas DataFrame 中包含列表的列的嵌套?

Barbara Streisand
Barbara Streisand原创
2024-12-20 22:58:14957浏览

How to Unnest List-Containing Columns in Pandas DataFrames?

如何将 Pandas DataFrame 中的列取消嵌套(分解)为多行

在 pandas 中,您可能会遇到列包含列表或对象作为元素。要将这样的列转换为单独的行,需要一个称为“取消嵌套”或“爆炸”的过程。这使您可以更有效地可视化和分析数据。

问题:

考虑一个 DataFrame,其中一列“B”包含列表:

df = pd.DataFrame({'A': [1, 2], 'B': [[1, 2], [1, 2]]})

   A       B
0  1  [1, 2]
1  2  [1, 2]

预计输出:

所需的输出是一个 DataFrame,其中“B”列的每个元素表示为单独的行:

   A  B
0  1  1
1  1  2
3  2  1
4  2  2

解决方案:

方法一:爆炸函数

从 Pandas 0.25 版本开始,可以使用 pandas.DataFrame.explode 函数进行取消嵌套。此函数有效地分解特定列,为每个列表元素创建新行。

df.explode('B')

   A  B
0  1  1
1  1  2
0  2  1
1  2  2

方法 2:应用 pd.Series

另一种方法是将 apply 结合起来与 pd.Series 的功能。此方法处理“B”列的每一行,并将其元素拆分为单独的 Series 对象。

df.set_index('A').B.apply(pd.Series).stack().reset_index(level=0).rename(columns={0:'B'})

方法 3:DataFrame 构造函数

或者,您可以使用 DataFrame 构造函数来重塑数据。这涉及重复行索引以匹配列表中的元素数量并将它们连接到单个列中。

df = pd.DataFrame({'A':df.A.repeat(df.B.str.len()), 'B':np.concatenate(df.B.values)})

方法 4:重新索引或 loc

使用 reindex 或 loc 允许您扩展 DataFrame 以容纳分解的值。使用“B”列中的元素填充缺失值。

df.reindex(df.index.repeat(df.B.str.len())).assign(B=np.concatenate(df.B.values))

方法 5:列表理解

一种简洁的方法涉及使用以下命令创建列表列表列表理解,然后将其转换为 DataFrame。

pd.DataFrame([[x] + [z] for x, y in df.values for z in y],columns=df.columns)

方法 6: Numpy

对于性能密集型场景,numpy 提供向量化运算。此方法使用 np.dstack 重塑数据并创建一个新的 DataFrame。

newvalues=np.dstack((np.repeat(df.A.values,list(map(len,df.B.values))),np.concatenate(df.B.values)))
pd.DataFrame(data=newvalues[0],columns=df.columns)

方法 7:Itertools

利用 itertools 包,您可以迭代元素并将它们组合起来创建一个新的DataFrame.

from itertools import cycle, chain
l=df.values.tolist()
l1=[list(zip([x[0]], cycle(x[1])) if len([x[0]]) > len(x[1]) else list(zip(cycle([x[0]]), x[1]))) for x in l]
pd.DataFrame(list(chain.from_iterable(l1)),columns=df.columns)

泛化为多列:

要将这些方法扩展到多列,您可以定义一个自定义函数,该函数将列名称作为输入并执行取消嵌套操作。

def unnesting(df, explode):
    idx = df.index.repeat(df[explode[0]].str.len())
    df1 = pd.concat([pd.DataFrame({x: np.concatenate(df[x].values)}) for x in explode], axis=1)
    df1.index = idx

    return df1.join(df.drop(explode, 1), how='left')

按列取消嵌套:

如果你想水平“取消嵌套”,即展开一行中的元素,可以使用 DataFrame 构造函数。

df.join(pd.DataFrame(df.B.tolist(),index=df.index).add_prefix('B_'))

结论:

这些方法为取消 pandas DataFrame 中的数据嵌套提供了灵活的选项。选择最适合您的性能和可读性要求的方法。

以上是如何取消 Pandas DataFrame 中包含列表的列的嵌套?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn