高级Python pandas重塑技术

4
我认为这与这篇文章类似,但不完全相同,我无法理解它。
所以,我目前有一个(相当奇怪的)带有列表的pandas数据框,每个单元格都像这样:
>>> data = pd.DataFrame({'myid' : ['1', '2', '3'],
                         'num' : [['1', '2', '3'], ['1', '2'], []],
                         'text' : [['aa', 'bb', 'cc'], ['cc', 'dd'],
                         []]}).set_index('myid')

>>> print(data)
                num          text
    myid                         
    1     [1, 2, 3]  [aa, bb, cc]
    2        [1, 2]      [cc, dd]
    3            []            []

我希望能实现以下目标:
  myid num text
0    1   1   aa
0    1   2   bb
0    1   3   cc
1    2   1   cc
1    2   2   dd
2    3         

我该如何到达那里?

numtext 列中的数据类型实际上是列表吗?我问这个问题是因为当我将 neo4j 数据集输出到 pandas 时遇到了类似的情况,值不是列表,而是字符串。 - Scratch'N'Purr
你应该尽力提供易于复现的示例。 - juanpa.arrivillaga
@Scratch'N'Purr 很好的观点,我检查了一下,我的情况确实是列表。 - absurd
2个回答

6
我会使用 str.len 来确定嵌套列表/数组的长度。然后使用 repeatconcatenate
lens = df.num.str.len()

pd.DataFrame(dict(
        myid=df.myid.repeat(lens),
        num=np.concatenate(df.num),
        text=np.concatenate(df.text)
    )).append(
    pd.DataFrame(
        df.loc[~df.num.astype(bool), 'myid']
    )
).fillna('')

  myid num text
0    1   1   aa
0    1   2   bb
0    1   3   cc
1    2   1   cc
1    2   2   dd
2    3         

2
这是一个非常出色的解决方案! - MaxU - stand with Ukraine
我尝试根据你的答案创建一个更通用的解决方案。 - MaxU - stand with Ukraine

2
我在这里尝试创建一个更通用的解决方案,基于聪明的@piRSquared的解决方案
DataFrame:
df = pd.DataFrame({
 'aaa': {0: 10, 1: 11, 2: 12, 3: 13},
 'myid': {0: 1, 1: 2, 2: 3, 3: 4},
 'num': {0: [1, 2, 3], 1: [1, 2], 2: [], 3: []},
 'text': {0: ['aa', 'bb', 'cc'], 1: ['cc', 'dd'], 2: [], 3: []}
})

解决方案:
lst_cols = ['num','text']
idx_cols = df.columns.difference(lst_cols)

lens = df[lst_cols[0]].str.len()

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('') \
  .loc[:, df.columns]

来源DF:
In [25]: df
Out[25]:
   aaa  myid        num          text
0   10     1  [1, 2, 3]  [aa, bb, cc]
1   11     2     [1, 2]      [cc, dd]
2   12     3         []            []
3   13     4         []            []

结果:

In [26]: 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('') \
    ...:   .loc[:, df.columns]
    ...:
Out[26]:
   aaa  myid num text
0   10     1   1   aa
1   10     1   2   bb
2   10     1   3   cc
3   11     2   1   cc
4   11     2   2   dd
2   12     3
3   13     4

1
谢谢MaxU。那肯定会很有用。 - absurd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接