我有以下数据帧,其中一列是一个对象(列表类型单元格):

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

输出:

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

我的期望输出是:

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

我该怎么做才能做到这一点呢?


相关的问题

Pandas列的列表,为每个列表元素创建一行

很好的问题和答案,但只处理一个列与列表(在我的回答自定义函数将工作于多个列,也接受的答案是使用最耗时的应用,这是不建议的,检查更多信息当我(不)想要使用熊猫应用()在我的代码?)


当前回答

下面是一个简单的水平爆炸函数,基于@BEN_YO的答案。

import typing
import pandas as pd

def horizontal_explode(df: pd.DataFrame, col_name: str, new_columns: typing.Union[list, None]=None) -> pd.DataFrame:
    t = pd.DataFrame(df[col_name].tolist(), columns=new_columns, index=df.index)
    return pd.concat([df, t], axis=1)

运行示例:

items = [
    ["1", ["a", "b", "c"]],
    ["2", ["d", "e", "f"]]
]

df = pd.DataFrame(items, columns = ["col1", "col2"])
print(df)

t = horizontal_explode(df=df, col_name="col2")
del t["col2"]
print(t)

t = horizontal_explode(df=df, col_name="col2", new_columns=["new_col1", "new_col2", "new_col3"])
del t["col2"]
print(t)

这是相关的输出:

  col1       col2
0    1  [a, b, c]
1    2  [d, e, f]

  col1  0  1  2
0    1  a  b  c
1    2  d  e  f

  col1 new_col1 new_col2 new_col3
0    1        a        b        c
1    2        d        e        f

其他回答

有些东西不太推荐(至少在这种情况下有用):

df=pd.concat([df]*2).sort_index()
it=iter(df['B'].tolist()[0]+df['B'].tolist()[0])
df['B']=df['B'].apply(lambda x:next(it))

Concat + sort_index + iter + apply + next。

Now:

print(df)

Is:

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

如果关心索引:

df=df.reset_index(drop=True)

Now:

print(df)

Is:

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

我有另一个好方法来解决这个问题当你有不止一列要爆炸的时候。

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

print(df)
   A       B          C
0  1  [1, 2]  [1, 2, 3]
1  2  [1, 2]  [1, 2, 3]

我想爆炸B和C列,首先爆炸B,第二爆炸C,然后从原来的df中去掉B和C。之后,我将在3个dfs上做一个索引连接。

explode_b = df.explode('B')['B']
explode_c = df.explode('C')['C']
df = df.drop(['B', 'C'], axis=1)
df = df.join([explode_b, explode_c])

在我的例子中,有多个列要爆炸,并且需要取消嵌套的数组有变量长度。

我最终应用了新的熊猫0.25爆炸功能两次,然后删除生成的副本,它的工作!

df = df.explode('A')
df = df.explode('B')
df = df.drop_duplicates()

在pandas 0.25中,由于增加了explosion()方法,爆炸一个类似列表的列被大大简化了:

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

Out:

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

pd.concat([df['A'], pd.DataFrame(df['B'].values.tolist())], axis = 1)\
  .melt(id_vars = 'A', value_name = 'B')\
  .dropna()\
  .drop('variable', axis = 1)

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

对我想到的这个方法有什么意见吗?或者同时做concat和melt被认为太“昂贵”?