pandas pos_explode-数组的嵌套列,但保留索引

时间:2019-05-12 11:33:03

标签: python arrays pandas

我想在熊猫中拥有类似于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为[1,2,3]。

       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

1 个答案:

答案 0 :(得分:1)

您可以使用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