вставка списка в качестве столбца в фрейм данных в указанном c месте в зависимости от значения в строке - PullRequest
0 голосов
/ 28 мая 2020

, так что у меня есть фрейм данных (файл tsv / csv) с использованием numpy, pandas и statsmodels.

В одном столбце «medianame» будет отображаться имя носителя (стимул) экран (этот стимул движется. Каждая строка представляет отметку времени).

Каждый раз, когда в этом столбце появляется указанное c имя мультимедиа (в этом примере, скажем, «стимул1»), пора вставьте список , скажем, 5 чисел в другой столбец, начиная с этой строки.

Остальные элементы в столбце должны быть пустыми (np.nan).

Другое требование состоит в том, что его нужно вставлять каждый раз, когда имя появляется «снова» в столбце «medianame». Таким образом, возможно, что количество элементов в списке меньше, чем количество последовательных вхождений медианного имени (см. Первый случай в примере ниже).

Если количество элементов в списке больше, чем количество последовательных вхождений медианного имени, оно должно быть отключено раньше (см. Второй случай в примере ниже).

Пример:

List1 = [5, 7, 1, 8, 9] # to be inserted in column "position"
                        # when medianame "stimulus1" appears in column "medianame"

medianame
stimulus0
stimulus0
stimulus0
stimulus0
stimulus0
stimulus0
NaN
stimulus1
stimulus1
stimulus1
stimulus1
stimulus1
stimulus1
stimulus1
stimulus1
stimulus1
stimulus1
NaN
stimulus2
stimulus2
stimulus2
stimulus2
stimulus2
NaN
stimulus1
stimulus1
stimulus1

Надеемся, что после добавления в нужном месте он будет выглядеть так:

medianame     position
stimulus0     NaN
stimulus0     NaN
stimulus0     NaN
stimulus0     NaN
stimulus0     NaN
stimulus0     NaN
NaN           NaN
stimulus1     5
stimulus1     7
stimulus1     1
stimulus1     8
stimulus1     9
stimulus1     NaN
stimulus1     NaN
stimulus1     NaN
stimulus1     NaN
stimulus1     NaN
NaN           NaN
stimulus2     NaN
stimulus2     NaN
stimulus2     NaN
stimulus2     NaN
stimulus2     NaN
NaN           NaN
stimulus1     5
stimulus1     7
stimulus1     1

1 Ответ

0 голосов
/ 28 мая 2020

Вот один из способов использования merge с groupby, cumsum и конструктором pd.Series:

df.assign(key = df.groupby((df['medianame'] != 'stimulus1').cumsum()).cumcount())\
  .merge(pd.Series(List1, index=range(1,len(List1)+1)).rename('position'), 
         left_on='key', 
         right_index=True, 
         how='left')\
  .drop('key', axis=1)

Вывод:

    medianame  position
0   stimulus0       NaN
1   stimulus0       NaN
2   stimulus0       NaN
3   stimulus0       NaN
4   stimulus0       NaN
5   stimulus0       NaN
6         NaN       NaN
7   stimulus1       5.0
8   stimulus1       7.0
9   stimulus1       1.0
10  stimulus1       8.0
11  stimulus1       9.0
12  stimulus1       NaN
13  stimulus1       NaN
14  stimulus1       NaN
15  stimulus1       NaN
16  stimulus1       NaN
17        NaN       NaN
18  stimulus2       NaN
19  stimulus2       NaN
20  stimulus2       NaN
21  stimulus2       NaN
22  stimulus2       NaN
23        NaN       NaN
24  stimulus1       5.0
25  stimulus1       7.0
26  stimulus1       1.0

Подробности

Создайте серию s с диапазоном индексов, начинающимся с 1:

s = pd.Series(List1, index=range(1,len(List1)+1)).rename('position')

Вывод:

1    5
2    7
3    1
4    8
5    9
Name: position, dtype: int64

Теперь давайте присоединим эту серию к кадру данных df, где «стимул1», но сначала нам нужно создать ключ соединения на df.

df_key = df.assign(key = df.groupby((df['medianame'] != 'stimulus1').cumsum()).cumcount())

Вывод:

    medianame  key
0   stimulus0    0
1   stimulus0    0
2   stimulus0    0
3   stimulus0    0
4   stimulus0    0
5   stimulus0    0
6         NaN    0
7   stimulus1    1
8   stimulus1    2
9   stimulus1    3
10  stimulus1    4
11  stimulus1    5
12  stimulus1    6
13  stimulus1    7
14  stimulus1    8
15  stimulus1    9
16  stimulus1   10
17        NaN    0
18  stimulus2    0
19  stimulus2    0
20  stimulus2    0
21  stimulus2    0
22  stimulus2    0
23        NaN    0
24  stimulus1    1
25  stimulus1    2
26  stimulus1    3

Наконец, объедините df_key с s how = 'left' на ключе и s.index:

df_key.merge(s, how='left', left_on='key', right_index=True)

Вывод:

    medianame  key  position
0   stimulus0    0       NaN
1   stimulus0    0       NaN
2   stimulus0    0       NaN
3   stimulus0    0       NaN
4   stimulus0    0       NaN
5   stimulus0    0       NaN
6         NaN    0       NaN
7   stimulus1    1       5.0
8   stimulus1    2       7.0
9   stimulus1    3       1.0
10  stimulus1    4       8.0
11  stimulus1    5       9.0
12  stimulus1    6       NaN
13  stimulus1    7       NaN
14  stimulus1    8       NaN
15  stimulus1    9       NaN
16  stimulus1   10       NaN
17        NaN    0       NaN
18  stimulus2    0       NaN
19  stimulus2    0       NaN
20  stimulus2    0       NaN
21  stimulus2    0       NaN
22  stimulus2    0       NaN
23        NaN    0       NaN
24  stimulus1    1       5.0
25  stimulus1    2       7.0
26  stimulus1    3       1.0

И, при желании, вы можете удалить этот ключевой столбец.

...