似乎需要将已爆炸的列和未爆炸的列分开。由于我们不能像往常一样将它们隐藏在索引中(给定C2)包含列表(不可散列),我们必须分离 DataFrame 然后重新加入。
# Convert to single series to explode
cols = ['C1', 'C4']
new_df = df[cols].stack().explode().to_frame()
# Enumerate groups then unstack
new_df = new_df.set_index(
new_df.groupby(level=[0, 1]).cumcount(),
append=True
).unstack(1).groupby(level=0).ffill()
# Join Back Unaffected columns
new_df = new_df.droplevel(0, axis=1).droplevel(1, axis=0).join(
df[df.columns.symmetric_difference(cols)]
)
# Re order columns and reset index
new_df = new_df.reindex(df.columns, axis=1).reset_index(drop=True)
new_df:
C1 C2 C3 C4
0 A [1] s1 123
1 B [1] s1 123
2 C [2] s2 321
3 D [3] s3 777
4 E [3] s3 111
5 F [4] s4 145
我们stack 将所有值放入一个系列中,然后将explode 一起转换回to_frame
cols = ['C1', 'C4']
new_df = df[cols].stack().explode().to_frame()
new_df
0
0 C1 A
C1 B
C4 123
1 C1 C
C4 321
2 C1 D
C1 E
C4 777
C4 111
3 C1 F
C4 145
我们可以用groupby cumcountset_index和unstacking枚举组来创建一个新索引:
new_df = new_df.set_index(
new_df.groupby(level=[0, 1]).cumcount(),
append=True
).unstack(1)
0
C1 C4
0 0 A 123
1 B NaN
1 0 C 321
2 0 D 777
1 E 111
3 0 F 145
然后我们可以在索引组中groupby ffill:
new_df = new_df.groupby(level=0).ffill()
new_df:
0
C1 C4
0 0 A 123
1 B 123
1 0 C 321
2 0 D 777
1 E 111
3 0 F 145
然后我们可以join 将未受影响的列返回到 DataFrame,reindex 以最初出现的方式重新排序它们,droplevel 以删除不需要的索引级别,最后是reset_index:
# Join Back Unaffected columns
new_df = new_df.droplevel(0, axis=1).droplevel(1, axis=0).join(
df[df.columns.symmetric_difference(cols)]
)
# Re order columns and reset index
new_df = new_df.reindex(df.columns, axis=1).reset_index(drop=True)
new_df:
C1 C2 C3 C4
0 A [1] s1 123
1 B [1] s1 123
2 C [2] s2 321
3 D [3] s3 777
4 E [3] s3 111
5 F [4] s4 145