Добавление строк в группы в Pandas DataFrame - PullRequest
1 голос
/ 09 мая 2019

У меня есть следующий DataFrame Pandas:

     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.

Для каждой такой группы, если в имени столбца «Гнев» и «Счастье» нет, я бы хотел вставить его с рейтингом 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 ]

3 голосов
/ 09 мая 2019

Вариант 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
3 голосов
/ 09 мая 2019

Я использую 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...