Добавить два новых столбца в структуру данных, используя значения из существующего столбца в зависимости от условий - PullRequest
0 голосов
/ 27 сентября 2019

Скажем, у меня есть кадр данных, который выглядит следующим образом.

 df.head()
    ID  col1    col2    col3    col4    type
    1   146       91      Rp    Rp-203  ex
    1   146      314      Rp    Rp-203  trans
    1   603       91      Rp    Rp-203  CDS
    1   910       81      Rp    Rp-203  CDS
    1   910       81      Rp    Rp-203  ex
    1   202      825      Rp    Rp-203  CDS
    1   202      837      Rp    Rp-203  ex
    1   200      314      Rp    Rp-203  ex

Из приведенного выше фрейма данных я хочу сгенерировать фреймы данных.Фрейм данных основан на условии, если столбец type равен ex.Кроме того, новый фрейм данных должен иметь два дополнительных столбца со значениями, разделенными запятыми на основе col1 и col2.

Я хочу создать два столбца col5 и col6, используя значения из col1 и col2 для каждого значения в столбцах col4 и type.То есть, я хочу сгруппировать по столбцу col3 для значений (ex) в столбце type.

В конце я стремлюсь иметь фреймы данных как,

ID  col1    col2    col3    col4    ex_start    ex_end
1   146     314     Rp      Rp-203  091,081,837 910,202,200

Я пробовал следующее решение,

df2 = df.loc[df['type']=='ex', ['col3','col1', 'col2',]].groupby(['col3']).agg(
        lambda x: ','.join([str(y) for y in x]))

Однако мое решение захватывает первое значение col1 как первое значение ex_start.Но мне нужно значение col2 в качестве первого значения в столбце ex_start df2.И значение col1 в качестве первого значения столбца ex_end в df2 и так далее.И столбец col1 и col2 в df2 должен принимать значения из df столбцов col1 и col2, если столбец type равен trans.

Любая помощь / предложения очень ценятся!

Ответы [ 2 ]

1 голос
/ 27 сентября 2019

Это мой подход к групповому режиму и функции для обработки

def join(group):
    ex = group[["col1", "col2"]].copy().values
    row = group.iloc[0]
    row[["col1", "col2"]] = (ex[0,0], ex[-1,1])
    row["ex_start"] = ",".join(ex[1:,0].astype(str))
    row["ex_end"] = ",".join(ex[:-1,1].astype(str))

    return row

df.groupby("type").apply(join)

, чтобы получить строку из только что вы можете сделать

df.groupby("type").apply(join).loc[["ex"]]

Вывод

ID  col1    col2    col3    col4    type    ex_start    ex_end
type                                
CDS 1   603 825 Rp  Rp-203  CDS 910,202 91,81
ex  1   146 314 Rp  Rp-203  ex  910,202,200 91,81,837
trans   1   146 314 Rp  Rp-203  trans       
1 голос
/ 27 сентября 2019

Использование:

#filter only ex rows by type
df3 = df[df['type']=='ex'].copy()

#shift values per groups from list
df3['s'] = df3.groupby(['ID','col3', 'col4'])['col2'].shift()
#removed NaNs rows per start and convert values to int and strings
df3 = df3.dropna(subset=['s']).assign(ex_start = lambda x: x['s'].astype(int).astype(str),
                                      ex_end = lambda x: x['col1'].astype(str))
print (df3)
   ID  col1  col2 col3    col4 type      s ex_start ex_end
4   1   910    81   Rp  Rp-203   ex   91.0       91    910
6   1   202   837   Rp  Rp-203   ex   81.0       81    202
7   1   200   314   Rp  Rp-203   ex  837.0      837    200

#then aggregate join
df4 = df3.groupby(['ID','col3', 'col4'])['ex_start','ex_end'].agg(','.join).reset_index()
print (df4)
   ID col3    col4   ex_start       ex_end
0   1   Rp  Rp-203  91,81,837  910,202,200

#filter by trans first rows per groups
df5 = df[df['type']=='trans'].drop_duplicates(['ID','col3', 'col4']).drop('type', 1)
print (df5)
   ID  col1  col2 col3    col4
1   1   146   314   Rp  Rp-203

#and add df5
df = df5.merge(df4)
print (df)
   ID  col1  col2 col3    col4   ex_start       ex_end
0   1   146   314   Rp  Rp-203  91,81,837  910,202,200
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...