Преобразование фрейма данных Pandas — понимание проблем с функциями, которые я должен использовать, и логикой, которую я должен выбрать

#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 Всегда пожалуйста! Я рад, что смог помочь 😉