在Pandas DataFrame中向组添加行

时间:2019-05-09 14:56:21

标签: python pandas dataframe pandas-groupby

我有以下Pandas DataFrame:

     start_timestamp_milli  end_timestamp_milli       name  rating
1            1555414708025        1555414723279    Valence       2   
2            1555414708025        1555414723279    Arousal       6   
3            1555414708025        1555414723279  Dominance       2   
4            1555414708025        1555414723279    Sadness       1   
5            1555414813304        1555414831795    Valence       3   
6            1555414813304        1555414831795    Arousal       5   
7            1555414813304        1555414831795  Dominance       2   
8            1555414813304        1555414831795    Sadness       1   
9            1555414921819        1555414931382    Valence       1   
10           1555414921819        1555414931382    Arousal       7   
11           1555414921819        1555414931382  Dominance       2   
12           1555414921819        1555414931382    Sadness       1   
13           1555414921819        1555414931382      Anger       1 

在上面的示例中,可以将三个组按start_timestamp_milli和end_timestamp_milli分组。第一组为索引1至4,第二组为索引5-8,第三组为索引9至13。

对于每个这样的组,如果在名称栏中没有“ Anger”和“ Happiness”,我想以0的等级插入它。如果存在,则什么也不会发生。

最终结果应如下所示。添加的行是第5、6、11、12和18行。

     start_timestamp_milli  end_timestamp_milli       name  rating
1            1555414708025        1555414723279    Valence       2   
2            1555414708025        1555414723279    Arousal       6   
3            1555414708025        1555414723279  Dominance       2   
4            1555414708025        1555414723279    Sadness       1
5            1555414708025        1555414723279    Happiness     0
6            1555414708025        1555414723279    Anger         0
7            1555414813304        1555414831795    Valence       3   
8            1555414813304        1555414831795    Arousal       5   
9            1555414813304        1555414831795  Dominance       2   
10           1555414813304        1555414831795    Sadness       1
11           1555414813304        1555414831795    Happiness     0
12           1555414813304        1555414831795    Anger         0   
13           1555414921819        1555414931382    Valence       1   
14           1555414921819        1555414931382    Arousal       7   
15           1555414921819        1555414931382  Dominance       2   
16           1555414921819        1555414931382    Sadness       1 
17           1555414921819        1555414931382   Happiness      0  
18           1555414921819        1555414931382      Anger       1 

这怎么办?

2 个答案:

答案 0 :(得分:3)

我正在使用unstack + stack + reindex

s=set(df.name.unique().tolist()+['Anger','Happiness'])

df.set_index(df.columns[:-1].tolist()).rating.\
    unstack(fill_value=0).\
       reindex(columns=s,fill_value=0).\ 
           stack().reset_index()

答案 1 :(得分:3)

选项1

这非常明确地循环遍历每个组,并追加了虚拟数据帧并删除了重复项。

d = dict(name=['Anger', 'Happiness'], rating=0)
cols = ['start_timestamp_milli', 'end_timestamp_milli']
def f(d0, k):
    d1 = pd.DataFrame({**dict(zip(cols, k)), **d})
    return d0.append(d1, ignore_index=True).drop_duplicates('name')

pd.concat([f(d, k) for k, d in df.groupby(cols)], ignore_index=True)

    start_timestamp_milli  end_timestamp_milli       name  rating
0           1555414708025        1555414723279    Valence       2
1           1555414708025        1555414723279    Arousal       6
2           1555414708025        1555414723279  Dominance       2
3           1555414708025        1555414723279    Sadness       1
4           1555414708025        1555414723279      Anger       0
5           1555414708025        1555414723279  Happiness       0
6           1555414813304        1555414831795    Valence       3
7           1555414813304        1555414831795    Arousal       5
8           1555414813304        1555414831795  Dominance       2
9           1555414813304        1555414831795    Sadness       1
10          1555414813304        1555414831795      Anger       0
11          1555414813304        1555414831795  Happiness       0
12          1555414921819        1555414931382    Valence       1
13          1555414921819        1555414931382    Arousal       7
14          1555414921819        1555414931382  Dominance       2
15          1555414921819        1555414931382    Sadness       1
16          1555414921819        1555414931382      Anger       1
17          1555414921819        1555414931382  Happiness       0

选项2

这将建立一个新索引并使用reindex

cats = ['Anger', 'Happiness']
cols = ['start_timestamp_milli', 'end_timestamp_milli']

d = df.set_index([*cols, 'name'])
i = pd.MultiIndex.from_tuples(
    [(s, e, n) for s, e in {*zip(*map(df.get, cols))} for n in cats],
    names=d.index.names
) | d.index

df.set_index([*cols, 'name']).reindex(i, fill_value=0).reset_index()

    start_timestamp_milli  end_timestamp_milli       name  rating
0           1555414708025        1555414723279      Anger       0
1           1555414708025        1555414723279    Arousal       6
2           1555414708025        1555414723279  Dominance       2
3           1555414708025        1555414723279  Happiness       0
4           1555414708025        1555414723279    Sadness       1
5           1555414708025        1555414723279    Valence       2
6           1555414813304        1555414831795      Anger       0
7           1555414813304        1555414831795    Arousal       5
8           1555414813304        1555414831795  Dominance       2
9           1555414813304        1555414831795  Happiness       0
10          1555414813304        1555414831795    Sadness       1
11          1555414813304        1555414831795    Valence       3
12          1555414921819        1555414931382      Anger       1
13          1555414921819        1555414931382    Arousal       7
14          1555414921819        1555414931382  Dominance       2
15          1555414921819        1555414931382  Happiness       0
16          1555414921819        1555414931382    Sadness       1
17          1555414921819        1555414931382    Valence       1