#pandas #dataframe
Вопрос:
У меня сложная проблема с преобразованием фрейма данных в другой.
Я не знаю, какие функции я должен использовать, чтобы делать то, что я хочу. У меня было несколько идей, которые вообще не сработали.
Например, я не понимаю, как я должен использовать append (или должен ли я использовать его или что-то еще), чтобы делать то, что я хочу.
Вот мой оригинальный фрейм данных:
df1 = pd.DataFrame({
'Key': ['K0', 'K1', 'K2'],
'X0': ['a','b','a'],
'Y0': ['c','d','c'],
'X1': ['e','f','f'],
'Y1': ['g','h','h']
})
Key X0 Y0 X1 Y1
0 K0 a c e g
1 K1 b d f h
2 K2 a c f h
Этот фрейм данных представляет все ссылки, прикрепленные к идентификатору в ключе столбца. Ссылки следуют друг за другом: X0-> Y0 является отцом X1-> Y1.
Он легко читается, и реальный фрейм данных, с которым я работаю, содержит 6500 строк по 21 столбцу, что представляет собой дерево ссылок. Итак, этот фрейм данных имеет логику сквозных ссылок.
Я хочу преобразовать его в другой, который имеет логику unitary links и ID (поскольку это дерево ссылок, некоторые унитарные ссылки могут быть частью нескольких сквозных ссылок)
Итак, я хочу получить каждую отдельную ссылку в X-> Y, и мне нужно получить список ключей, прикрепленных к каждой унитарной ссылке, в ключи.
И вот чего я хочу :
df3 = pd.DataFrame({
'Key':[['K0','K2'],'K1','K0',['K1','K2']],
'X':['a','b','e','f'],
'Y':['c','d','g','h']
})
Key X Y
0 [K0, K2] a c
1 K1 b d
2 K0 e g
3 [K1, K2] f h
Для этого мне сначала нужно объединить X0 и X1 в уникальный столбец X, idem для Y0 и Y1 в уникальный столбец Y. В то же время мне нужно сохранить ключи, прикрепленные к ссылкам. Это первое преобразование приводит к созданию нового фрейма данных, содержащего всю исходную информацию с дубликатами, с которыми я буду иметь дело после получения df3.
Вот переходный фрейм данных :
df2 = pd.DataFrame({
'Key':['K0','K1','K2','K0','K1','K2'],
'X':['a','b','a','e','f','f'],
'Y':['c','d','c','g','h','h']
})
Key X Y
0 K0 a c
1 K1 b d
2 K2 a c
3 K0 e g
4 K1 f h
5 K2 f h
Transition from df1 to df2
For now, I did this to put X0,X1 and Y0,Y1 into X and Y :
Key = pd.Series(dtype=str)
X = pd.Series(dtype=str)
Y = pd.Series(dtype=str)
for i in df1.columns:
if 'K' in i:
Key = Key.append(df1[i], ignore_index=True)
elif 'X' in i:
X = X.append(df1[i], ignore_index=True)
elif 'Y' in i:
Y = Y.append(df1[i], ignore_index=True)
0 K0
1 K1
2 K2
dtype: object
0 a
1 b
2 a
3 e
4 f
5 f
dtype: object
0 c
1 d
2 c
3 g
4 h
5 h
dtype: object
Но я не знаю, как получить ключи, чтобы держать их перед нужными ссылками.
Кроме того, я делаю это для построения df2, но это странно, и я не понимаю, как я должен это делать :
df2 = pd.DataFrame({
'Key':Key,
'X':X,
'Y':Y
})
Key X Y
0 K0 a c
1 K1 b d
2 K2 a c
3 NaN e g
4 NaN f h
5 NaN f h
Я попытался использовать append, чтобы объединить столбцы X0, X1 и Y0, Y1 непосредственно в df2, но это оказалось полным беспорядком, не заполняя столбцы df2 содержимым столбцов df1. Я также попытался использовать append, чтобы поместить ключ серии, X и Y непосредственно в df2, но это дало мне X и Y в строках вместо столбцов.
Короче говоря, я совершенно запутался в этом. Я знаю, что может быть много программ, чтобы взять df1, превратиться в df2, а затем в df3. Я не прошу вас решать проблему за меня, но мне действительно нужна помощь в отношении функций, которые я должен использовать, или логики, которую я должен внедрить для достижения своей цели.
Ответ №1:
Чтобы преобразовать df1
в df2
то, что вы хотите изучить pandas.wide_to_long
.
https://pandas.pydata.org/docs/reference/api/pandas.wide_to_long.html
>>> df2 = pd.wide_to_long(df1, stubnames=['X','Y'], i='Key', j='num')
>>> df2
X Y
Key num
K0 0 a c
K1 0 b d
K2 0 a c
K0 1 e g
K1 1 f h
K2 1 f h
Вы можете удалить ненужный уровень «num» из индекса using droplevel
и превратить уровень индекса «Key» в столбец using reset_index
. Объединение всего в цепочку:
>>> df2 = (
pd.wide_to_long(df1, stubnames=['X','Y'], i='Key', j='num')
.droplevel(level='num')
.reset_index()
)
>>> df2
Key X Y
0 K0 a c
1 K1 b d
2 K2 a c
3 K0 e g
4 K1 f h
5 K2 f h
Наконец, чтобы получить df3
, вам просто нужно сгруппировать df2
по «X» и «Y» и объединить «Ключевые» группы в списки.
>>> df3 = df2.groupby(['X','Y'], as_index=False).agg(list)
>>> df3
X Y Key
0 a c [K0, K2]
1 b d [K1]
2 e g [K0]
3 f h [K1, K2]
Если вы не хотите, чтобы отдельные ключи были списками, вы можете сделать это вместо этого
>>> df3 = (
df2.groupby(['X','Y'], as_index=False)
.agg(lambda g: g.iloc[0] if len(g) == 1 else list(g))
)
>>> df3
X Y Key
0 a c [K0, K2]
1 b d K1
2 e g K0
3 f h [K1, K2]
Комментарии:
1. Привет! Спасибо за ваш ответ, это позволило мне сделать именно то, что я хотел сделать со своими данными. Действительно полезный ответ, я сожалею, что пока не могу поддержать его, но позже я это сделаю!
2. @Lemisourd Всегда пожалуйста! Я рад, что смог помочь 😉