Как преобразовать pandas групп в разные столбцы? - PullRequest
0 голосов
/ 09 июля 2020

У меня есть фрейм данных, как показано ниже.

unit time s1 s2 ....
1    1    2  3
1    2    4  5
1    3    9  7
2    1    5  2
2    2    3  1

Я хотел бы сгруппировать данные по единицам, сохранить минимальное аналогичное количество последних наблюдений в зависимости от времени (блок 2 имеет 2 наблюдения) и сделать отдельная группа для столбца s1. Итак, примерно так.

unit_1 unit_2 
   4      5 
   9      3

Спасибо.

Ответы [ 3 ]

2 голосов
/ 09 июля 2020

Это должно решить вашу проблему -

def f(col):
    #First step is to get the last 2 for each group using .tail(2)
    dff = df[['unit','time',col]].sort_values(by=['unit','time'],axis=0).groupby(['unit']).tail(2)

    #Next we need the ordered rank of the time values instead of the actual values of time, 
    #since then we can keep the time values 2,3 as 1,2 and 1,2 as 1,2.
    dff['time'] = dff.groupby(['unit']).rank()

    #Last we pivot over the time and units to get the columns that you need for correlation analysis
    dff = dff.pivot(index='time',columns='unit',values=col).reset_index(drop=True).add_prefix('unit_')
    return dff

f('s1')
unit    unit_1  unit_2
   0         4       5
   1         9       3

Используйте эту функцию для более быстрого выполнения.

def f(col):
    filt = df[['unit',col]].groupby('unit').tail(2)  #filter last 2
    filt['count'] = filt.groupby('unit').cumcount()  #add a counter column for pivot
    
    #Use counter column as index and unit as column for pivot, then add prefix
    filt = filt.pivot(index='count',columns='unit',values=col).reset_index(drop=True).add_prefix("unit_")
    return filt
1 голос
/ 09 июля 2020

Итак, я сделал следующее решение:

import pandas as pd
import numpy as np

df = pd.DataFrame({'units': [1,1,1,2,2], 's1':[2,4,9,5,3]})

new_df = df.groupby('units').tail(2) # Taking the last 2 values
new_df
Out:
     units s1
    1   1   4
    2   1   9
    3   2   5
    4   2   3


units_list = new_df.units.unique() # How many units do we have?
units_columns = [] # For col names
form_dict = {}
# We have 2 values for each unit, so the number of elements is 2n, 
# where n is a number of unit corresponding the new_df.
n = 0

for unit in units_list:
    units_columns.append('unit_{}'.format(unit))

while n != len(new_df['s1']):
    for col in units_columns:
        form_dict.update({col:new_df['s1'][n:n+2].values})
        n += 2
        
final_df = pd.DataFrame(form_dict)
final_df

И результат:

 unit_1 unit_2
0   4   5
1   9   3
1 голос
/ 09 июля 2020

Groupby unit и передайте список значений nth Удалите ненужные столбцы. Транспонируйте фрейм данных и добавьте к именам блок префикса. Транспонировать и перемещать, чтобы объединить столбцы

   g= df.groupby('unit', group_keys=False).nth([-1,-2]).drop(columns=['time','s2']).T.add_prefix('unit_')#.unstack('s1')

final = pd.DataFrame({'unit_1': g['unit_1'].values.T.ravel(),
                    'unit_2': g['unit_2'].values.T.ravel()})
final

    unit_1  unit_2
0       4       5
1       9       3
...