Как создать новый столбец df из строк других строк с условиями?

1

У меня есть dataFrame с именами и типами. Мне нужно создать "newType" -column, используя shift для столбца "Тип". Мои данные:

ind   name    Type
____________________
1     sasha   a      
2     sasha   e
3     sasha   d
4     sasha   t
5     sasha   t
6     sasha   w
7     nik     e
8     nik     e
9     nik     q
10    nik     t
11    nik     h
12    nik     j
13    bob     k
14    bob     y
15    bob     r
16    bob     w
17    bob     t
18    bob     w

Мне нужно создать новый столбец, используя window = n для "Тип" -column с условием "name" -column. Если строки в моем окне имеют разные имена, мы возвращаем NaN.

размер окна = 3, окно выглядит так

[Тип [i-1], Тип [i], Тип [i + 1]]

размер = 4

[Тип [i-2], Тип [i-1], Тип [i], Тип [i + 1]]

размер = 5

[Тип [i-3], Тип [i-2], Тип [i-1], Тип [i], Тип [i + 1]]

...так далее

Иллюстрация для окна = 4: Изображение: визуализация алгоритма

Результат, который мне нужен:

ind   name    Type   newType
____________________________
1     sasha   a       NaN 
2     sasha   e       NaN
3     sasha   d       aedt
4     sasha   t       edtt
5     sasha   t       dttw
6     sasha   w       NaN
7     nik     e       NaN
8     nik     e       NaN
9     nik     q       eeqt
10    nik     t       eqth
11    nik     h       qthj
12    nik     j       NaN
13    bob     k       NaN
14    bob     y       NaN
15    bob     r       kyrw
16    bob     w       yrwt
17    bob     t       rwtw
18    bob     w       NaN

Как это сделать?

Теги:
pandas
dataframe

1 ответ

0

Это, вероятно, не выполняется наиболее эффективным способом, но опять же это несколько сложная операция. Я некоторое время пытался использовать функции катания или расширения, но безуспешно (поскольку они, похоже, работают только с численными аргументами). Вот мой метод для достижения желаемого результата:

from io import StringIO
import pandas as pd
import numpy as np
# Make DataFrame
df = pd.read_table(StringIO("""ind   name    Type
1     sasha   a      
2     sasha   e
3     sasha   d
4     sasha   t
5     sasha   t
6     sasha   w
7     nik     e
8     nik     e
9     nik     q
10    nik     t
11    nik     h
12    nik     j
13    bob     k
14    bob     y
15    bob     r
16    bob     w
17    bob     t
18    bob     w"""), sep='\s+')
def joiner(r):
    return "-".join(r.values)
df.set_index('name', inplace=True)
# Make new column which join letters aggregated by name
df['full_join'] = df.groupby('name')['Type'].apply(joiner)
df['full_join'].ffill(inplace=True)
df.reset_index(inplace=True)
a = df.full_join.str.split("-",expand=True)
b = []
w = 4 # window
# This part is probably not as efficient as it could be
for i in range(len(a)):
    j = i % len(a.iloc[i].str.split('-'))
    b.append("".join(a.iloc[i,j-(w-1):j+1].tolist()))
df['result'] = b
df['result'] = df['result'].shift(-1)
df.loc[df['result'] == "", 'result'] = np.nan
df.drop(columns=['full_join'], inplace=True)

Результат:

Out[135]: 
     name  ind Type result
0   sasha    1    a    NaN
1   sasha    2    e    NaN
2   sasha    3    d   aedt
3   sasha    4    t   edtt
4   sasha    5    t   dttw
5   sasha    6    w    NaN
6     nik    7    e    NaN
7     nik    8    e    NaN
8     nik    9    q   eeqt
9     nik   10    t   eqth
10    nik   11    h   qthj
11    nik   12    j    NaN
12    bob   13    k    NaN
13    bob   14    y    NaN
14    bob   15    r   kyrw
15    bob   16    w   yrwt
16    bob   17    t   rwtw
17    bob   18    w    NaN

Приятно удивил, что это закончилось тем же успехом и для других окон (я тестировал 2, 3 и 5). К сожалению, при добавлении строки в nik :(

Ещё вопросы

Сообщество Overcoder
Наверх
Меню