首页 > 解决方案 > pandas pos_explode - 未嵌套的数组列但保留索引

问题描述

我想在熊猫中有类似于 pos_explode 的东西,即将元素的索引保留在原始数组中。

df = pd.DataFrame({'metric': {24: 53, 68: 93, 86: 38},
 'label': {24: 1, 68: 1, 86: 1},
 'group_1': {24: 1, 68: 1, 86: 1},
 'group_2': {24: 1, 68: 1, 86: 1},
 'metric_group_0': {24: np.array([72, 41, 96]),
  68: np.array([85, 56, 33]),
  86: np.array([26, 85, 26])}})
df = df.reset_index(drop=True)
df = df.reset_index(drop=False)
df = df.set_index(['index'])
display(df)
s=pd.DataFrame({'metric_group_0':np.concatenate(df.metric_group_0.values)},index=df.index.repeat(df.metric_group_0.str.len()))
display(s)
s.join(df.drop('metric_group_0',1),how='left')

这会爆炸数据,但会丢失索引。如何将索引保留为附加列?即在本例中,每个pandas.Index.

       metric  label  group_1  group_2 metric_group_0
index                                                
0          53      1        1        1   [72, 41, 96]
1          93      1        1        1   [85, 56, 33]
2          38      1        1        1   [26, 85, 26]

目前转换为:

       metric_group_0  metric  label  group_1  group_2
index                                                 
0                  72      53      1        1        1
0                  41      53      1        1        1
0                  96      53      1        1        1
1                  85      93      1        1        1
1                  56      93      1        1        1
1                  33      93      1        1        1
2                  26      38      1        1        1
2                  85      38      1        1        1
2                  26      38      1        1        1

但缺少原始索引。所需的输出如下所示:

       metric_group_0  metric  label  group_1  group_2 pos_in_array
index                                                 
0                  72      53      1        1        1  1
0                  41      53      1        1        1  2
0                  96      53      1        1        1  3
1                  85      93      1        1        1  1
1                  56      93      1        1        1  2
1                  33      93      1        1        1  3
2                  26      38      1        1        1  1
2                  85      38      1        1        1  2
2                  26      38      1        1        1  3

标签: pythonarrayspandas

解决方案


您可以使用创建此列,groupby.cumcount我们将其index用作组:

df['pos_in_array'] = df.groupby(df.index).cumcount()+1

print(df)
       metric_group_0  metric  label  group_1  group_2  pos_in_array
index                                                               
0                  72      53      1        1        1             1
0                  41      53      1        1        1             2
0                  96      53      1        1        1             3
1                  85      93      1        1        1             1
1                  56      93      1        1        1             2
1                  33      93      1        1        1             3
2                  26      38      1        1        1             1
2                  85      38      1        1        1             2
2                  26      38      1        1        1             3

因此,您的整个代码如下所示,因为您尚未将新创建的数据框分配给变量:

df = df.reset_index(drop=True)
df = df.reset_index(drop=False)
df = df.set_index(['index'])

s=pd.DataFrame({'metric_group_0':np.concatenate(df.metric_group_0.values)},
               index=df.index.repeat(df.metric_group_0.str.len()))

df = s.join(df.drop('metric_group_0',1),how='left')

df['pos_in_array'] = df.groupby(df.index).cumcount()+1

推荐阅读