当前位置: 首页 > 面试题库 >

取消嵌套(爆炸)pandas DataFrame中的多个列表列的有效方法

司英飙
2023-03-14
问题内容

我正在将多个JSON对象读取到一个DataFrame中。问题在于某些列是列表。而且,数据非常大,因此我无法使用互联网上可用的解决方案。它们非常慢并且内存效率低下

这是我的数据的样子:

df = pd.DataFrame({'A': ['x1','x2','x3', 'x4'], 'B':[['v1','v2'],['v3','v4'],['v5','v6'],['v7','v8']], 'C':[['c1','c2'],['c3','c4'],['c5','c6'],['c7','c8']],'D':[['d1','d2'],['d3','d4'],['d5','d6'],['d7','d8']], 'E':[['e1','e2'],['e3','e4'],['e5','e6'],['e7','e8']]})
    A       B          C           D           E
0   x1  [v1, v2]    [c1, c2]    [d1, d2]    [e1, e2]
1   x2  [v3, v4]    [c3, c4]    [d3, d4]    [e3, e4]
2   x3  [v5, v6]    [c5, c6]    [d5, d6]    [e5, e6]
3   x4  [v7, v8]    [c7, c8]    [d7, d8]    [e7, e8]

这就是我的数据的形状:(441079,12)

我想要的输出是:

    A       B          C           D           E
0   x1      v1         c1         d1          e1
0   x1      v2         c2         d2          e2
1   x2      v3         c3         d3          e3
1   x2      v4         c4         d4          e4
.....

编辑:标记为重复后,我想强调一个事实,在这个问题中,我正在寻找一种爆炸多列的 有效
方法。因此,批准的答案能够有效地爆炸非常大的数据集上的任意数量的列。另一个问题的答案无法解决(这就是我测试这些解决方案后问这个问题的原因)。


问题答案:
def explode(df, lst_cols, fill_value=''):
    # make sure `lst_cols` is a list
    if lst_cols and not isinstance(lst_cols, list):
        lst_cols = [lst_cols]
    # all columns except `lst_cols`
    idx_cols = df.columns.difference(lst_cols)

    # calculate lengths of lists
    lens = df[lst_cols[0]].str.len()

    if (lens > 0).all():
        # ALL lists in cells aren't empty
        return pd.DataFrame({
            col:np.repeat(df[col].values, df[lst_cols[0]].str.len())
            for col in idx_cols
        }).assign(**{col:np.concatenate(df[col].values) for col in lst_cols}) \
          .loc[:, df.columns]
    else:
        # at least one list in cells is empty
        return pd.DataFrame({
            col:np.repeat(df[col].values, df[lst_cols[0]].str.len())
            for col in idx_cols
        }).assign(**{col:np.concatenate(df[col].values) for col in lst_cols}) \
          .append(df.loc[lens==0, idx_cols]).fillna(fill_value) \
          .loc[:, df.columns]

用法:

In [82]: explode(df, lst_cols=list('BCDE'))
Out[82]:
    A   B   C   D   E
0  x1  v1  c1  d1  e1
1  x1  v2  c2  d2  e2
2  x2  v3  c3  d3  e3
3  x2  v4  c4  d4  e4
4  x3  v5  c5  d5  e5
5  x3  v6  c6  d6  e6
6  x4  v7  c7  d7  e7
7  x4  v8  c8  d8  e8


 类似资料:
  • 我正在使用Spark SQL(我提到它是在Spark中,以防影响SQL语法-我还不太熟悉,还不能确定),我有一个表,我正在尝试重新构造,但我在尝试同时转置多个列时遇到了麻烦。 基本上,我有看起来像这样的数据: 并且我想同时分解varA和varB(长度将始终保持一致) - 因此最终输出如下所示: 但是我似乎只能让一个explee(var)语句在一个命令中工作,如果我尝试链接它们(即在第一个分解命令之

  • 我有一个模式,其中每行包含多个数组列,我想独立于每个数组列爆炸。 假设我们有列: 我想要一个输出: 想法? (哦,我正在尝试这样做,所以我不必随着模式的变化而更新代码,也因为实际的模式有点大…) PS -支持这个非常相似但不同的问题,我无耻地从这个问题中窃取了示例数据。 编辑:@oliik赢了,但是,如果能用<code>df来实现这一点,那也太棒了。flatMap(主要是因为我仍然不去摸索<cod

  • 问题内容: 我了解简单列表理解的工作原理,例如: 而且我也了解嵌套列表的综合工作原理: 所以,当我尝试这样做 我期望这样: 但是我得到了: 所以我有更好的方法解决问题,这给了我我想要的 但是我不明白在第一个代码中返回9个元素 问题答案: 它有9个数字的原因是因为python对待 类似于 即,它是一个嵌套循环

  • 尝试使用这个资源:仍然不走运,我如何从Java8 Stream的一些类属性中获得列表?

  • 问题内容: 试图了解如何在Firebase中实现嵌套列表。 可以解决的问题:1-to-N消息传递系统,对于每个消息,您希望维护一个已接收和阅读该消息的用户列表。 阅读了“ Firebase中阵列的最佳实践”。尝试避免使用数组,因为我要同时进行写操作,而在这里看来它们并不是一个好选择。 当前试图通过在每个消息下存储子树来实现此目的,每个子树是已接收,读取或以其他方式对消息 Y 执行某些操作 X 的用

  • 问题内容: 我有一个包含嵌套列表的列表,我需要知道在这些嵌套列表中搜索的最有效方法。 例如,如果我有 并且我必须搜索上面的整个列表,找到“ d”的最有效方法是什么? 问题答案: 使用列表推导,给出: 产量: 这也可以使用生成器来完成(如@AshwiniChaudhary所示) 根据以下评论进行更新: 这是相同的列表理解,但是使用了更具描述性的变量名: 列表理解部分中的循环构造等效于 并生成一个列表