Pandas - 分解 pandas 中的多个列并根据分解的列分配值

imp*_*rme 5 python numpy dataframe python-3.x pandas

可重现的例子:

ex = [{"explode1": ["a", "e", "i"], "word": "US_12", "explode2": []}, 
      {"explode1": [], "word": "US_34", "explode2": ["a", "e", "i"]}, 
      {"explode1": ["a", "e", "i"], "word": "US_56", "explode2": ["o", "u"]}]

df = pd.DataFrame(ex)
Run Code Online (Sandbox Code Playgroud)

给你

        explode1   word   explode2
    0  [a, e, i]  US_12         []
    1         []  US_34  [a, e, i]
    2  [a, e, i]  US_56     [o, u]
Run Code Online (Sandbox Code Playgroud)

您可以假设还有一个explode3和 一个explode4列(为了简洁而排除)

预期结果数据框:

   exploded_alphabet   word    exploded_type
0                  a  US_12    explode1
1                  e  US_12    explode1
2                  i  US_12    explode1
3                  a  US_34    explode2
4                  e  US_34    explode2
5                  i  US_34    explode2
6                  a  US_54    explode1
7                  e  US_54    explode1
8                  i  US_54    explode1
9                  o  US_34    explode2
10                 u  US_34    explode2
Run Code Online (Sandbox Code Playgroud)

该解决方案必须可以用 4 列重现,而不仅仅是上面提到的 2 列(为了简洁起见explode3,我没有将其包含在我的示例中)explode4

因此,总行数将等于explode1、explode2和展平中所有列表中的元素数。explode3explode4

我的努力:

老实说,我认为必须有一种更短的 Python 方式,而不是单独分解每个类型,然后分解具有多种类型的那些。

df = df.explode("explode1")
df = df.explode("explode2")
Run Code Online (Sandbox Code Playgroud)

以上是不正确的。因为这不会同时分解行。如果多个爆炸列中的列表非空,它会创建重复项。


另一种是非 Pythonic 方式,您可以逐行迭代并创建和分配一个新列 - 这是冗长且容易做到的。但这个问题可能已经以不同的方式解决了。


我的问题与其他“分解多列”问题有何不同?:

  1. 分别炸毁它们。这些列中的每个元素都会创建一个新行(这可能已经存在了)

  2. 分配值exploded_type- 不确定这个问题是否已与 1 一起解决。

jez*_*ael 4

使用DataFrame.meltbeforeexplode进行 unpivot,然后删除缺少值的行(从空列表中):

df = (df.melt('word', value_name='exploded_alphabet', var_name='exploded_type')
        .explode("exploded_alphabet")
        .dropna(subset=['exploded_alphabet'])
        .reset_index(drop=True))
print (df)
     word exploded_type exploded_alphabet
0   US_12      explode1                 a
1   US_12      explode1                 e
2   US_12      explode1                 i
3   US_56      explode1                 a
4   US_56      explode1                 e
5   US_56      explode1                 i
6   US_34      explode2                 a
7   US_34      explode2                 e
8   US_34      explode2                 i
9   US_56      explode2                 o
10  US_56      explode2                 u
Run Code Online (Sandbox Code Playgroud)