Предположим, у меня есть следующая таблица в csv.
elementID | groupID | sequence
abc | A | 0
dcv | A | 1
asd | B | 1
ccc | B | 0
abc | B | 2
Я импортировал эту таблицу в Pandas
как DataFrame.
Из этого DataFrame мне нужно создать еще один, где каждая запись представляет собой два последовательных элемента elementID
.
Например, что-то вроде следующего
elementID_1 | elementID_2 | groupID
abc | dcv | A
asd | abc | B
ccc | asd | B
Сначала я подумал о многострочном выделении, но не мог понять, как это сделать.
Поэтому я решил делать шаг за шагом, создавая по одному столбцу за раз.
Сначала я создал столбец elementID_2
следующим образом
new_df = pd.DataFrame()
new_df[["elementID_2", "sequence", "groupID"]] = old_df.loc[old_df.loc.sequence>1][["elementID", "sequence", "groupID"]]
Теперь, чтобы создать столбец elementID_1
, я хотел бы сопоставить записи старого фрейма данных, имеющие значение assequence
, значение sequence
нового фрейма данных минус 1 и такое же groupdID
между двумя фреймами данных.
Как я могу это сделать?
Вот один из способов использования groupby
+ itertools
s=df.groupby('groupID').elementID.apply(lambda x : set(itertools.combinations(x.values.tolist(), 2)))
df1=pd.DataFrame(s.index.repeat(s.str.len()))
df2=pd.DataFrame(list(itertools.chain(*s.tolist())))
pd.concat([df1,df2],axis=1)
Out[286]:
groupID 0 1
0 A abc dcv
1 B asd abc
2 B asd ccc
3 B ccc abc
@FrancescoBoi выглядит как проблема со сменой
IIUC, вы можете сделать это с помощью shift()
в группах и dropna
:
df.sort_values('sequence', inplace=True)
df['elementID_1'] = df.groupby('groupID').elementID.shift()
df.dropna()
Выход:
+----+-------------+-----------+------------+---------------+
| | elementID | groupID | sequence | elementID_1 |
|----+-------------+-----------+------------+---------------|
| 1 | dcv | A | 1 | abc |
| 2 | asd | B | 3 | ccc |
| 4 | abc | B | 4 | asd |
+----+-------------+-----------+------------+---------------+
Затем вы можете удалить столбец sequence
и переименовать elementID
в elementID_2
.
Разве он не должен быть отсортирован по groupID
первому и sequence
второму?
Нет необходимости сортировать groupID
, так как groupby
позаботится об этом. Но в этом нет ничего плохого, если вам это нужно еще и для того.
В моем вопросе есть двусмысленность: индексы A
и B
не являются последовательными: они могут иметь одинаковые значения (например, B
может снова начинаться с 0). Вот почему я спрашиваю. Я поправлю свой вопрос.
Это не имеет значения. Пока вы сортируете по sequence
, они будут отображаться в правильном порядке в каждом groupID
. Опять же, нет ничего плохого в дополнительной работе.
Почти ... Я попробовал свой исходный набор данных, и кажется, что таким образом создаются дополнительные записи, например, запись с
ccc
первой иabc
второй.