Как я могу изменить повторяющийся широкий pandas DataFrame, чтобы быть сложенным? - PullRequest
1 голос
/ 07 апреля 2020

У меня есть Pandas DataFrame, где респонденты отвечают на один и тот же вопрос через несколько учетных записей продаж. Мой входной Dataframe имеет следующий формат

df = pd.DataFrame({"Sales_Acc1":[100,300],
              "Sales_Acc2":[200,500],
              "Time_Acc1":[2,5],
              "Time_acc2":[6,9],
              "Acc_Number_acc1":[1001,1005],
              "Acc_Number_acc2":[1009,1010]},
             index=["John","Dave"])
df
>>> Sales_Acc1  Sales_Acc2  Time_Acc1   Time_acc2   Acc_Number_acc1 Acc_Number_acc2
John    100     200          2          6           1001            1009
Dave    300     500          5          9           1005            1010

Я хочу повернуть это так, чтобы у каждой учетной записи была своя собственная строка. Мой желаемый конечный Dataframe будет выглядеть так:

df
>>> AccountNumber   Rep   Sales   Time 
     1001           John  100     2
     1005           John  300     6
     1009           Dave  200     5
     1010           Dave  500     9

Я пытался использовать melt и pivot, но я не могу понять это. Я ценю любую помощь.

Ответы [ 2 ]

3 голосов
/ 07 апреля 2020

Это проблема wide_to_long, если ваш столбец в формате 'stub_SomeSuffix'. Поскольку у вас есть некоторые противоречивые случаи, мы сделаем все ниже. Нам также нужно удалить имена из index, поскольку wide_to_long требует столбцов.

df.columns = df.columns.str.lower()

df = (pd.wide_to_long(df.rename_axis('Rep').reset_index(),    # Use Rep as index
                      i='Rep',                                # index of output
                      j='will_drop',                          # Suffix labels  
                      stubnames=['sales', 'acc_number', 'time'],
                      sep='_', 
                      suffix='.*') 
        .reset_index()
        .drop(columns='will_drop'))

#    Rep  sales  acc_number  time
#0  John    100        1001     2
#1  Dave    300        1005     5
#2  John    200        1009     6
#3  Dave    500        1010     9

Если вы не являетесь поклонником бесконечных аргументов, требуемых с wide_to_long, мы можем вместо этого создайте простой MultiIndex для столбцов, а затем это stack. Опять же из-за непоследовательности корпуса мы делаем все столбцы полностью строчными.

df.columns = pd.MultiIndex.from_arrays(zip(*df.columns.str.lower().str.rsplit('_', n=1)))
#     sales      time      acc_number      
#      acc1 acc2 acc1 acc2       acc1  acc2
#John   100  200    2    6       1001  1009
#Dave   300  500    5    9       1005  1010

df.stack(-1).reset_index(-1, drop=True)
#      acc_number  sales  time
#John        1001    100     2
#John        1009    200     6
#Dave        1005    300     5
#Dave        1010    500     9
2 голосов
/ 07 апреля 2020
df1=df[['Sales_Acc1','Time_Acc1','Acc_Number_acc1']]
df2=df[['Sales_Acc2','Time_acc2','Acc_Number_acc2']]
df1.columns=['Sales_Acc','Time_Acc','Acc_Number']
df2.columns=['Sales_Acc','Time_Acc','Acc_Number']
df3 = df1.append(df2)
df3.index.names = ['Rep']

Мое решение так же просто, как и это, и оно будет работать в этом случае, мы в основном помещаем столбцы в разные строки.

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

Это полный код:

import pandas as pd
df = pd.DataFrame({"Sales_Acc1":[100,300],
              "Sales_Acc2":[200,500],
              "Time_Acc1":[2,5],
              "Time_acc2":[6,9],
              "Acc_Number_acc1":[1001,1005],
              "Acc_Number_acc2":[1009,1010]},
             index=["John","Dave"])
df1=df[['Sales_Acc1','Time_Acc1','Acc_Number_acc1']]
df2=df[['Sales_Acc2','Time_acc2','Acc_Number_acc2']]
df1.columns=['Sales_Acc','Time_Acc','Acc_Number']
df2.columns=['Sales_Acc','Time_Acc','Acc_Number']
df3 = df1.append(df2)
df3.index.names = ['Rep']
df3.head()

Вывод:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...