Pandas Pivot с пользовательскими столбцами

1

У меня есть dataframe, где у меня есть несколько переменных (здесь Var1 и Var2), которые различаются по разным местоположениям (здесь Station). Тогда у меня есть определенное количество случаев, и для каждого случая я получаю другое значение в каждом месте.

Так, например:

np.random.seed(42)

df1 = pd.DataFrame({'Station' : range(10)})
df1['ID'] = 'a'
df1['Var1'] = np.random.randn(10)
df1['Var2'] = np.random.randn(10)

df2 = pd.DataFrame({'Station' : range(10)})
df2['ID'] = 'b'
df2['Var1'] = np.random.randn(10)
df2['Var2'] = np.random.randn(10)

df = pd.concat([df1, df2])

Так выглядит:

   Station ID      Var1      Var2
0        0  a  0.496714 -0.463418
1        1  a -0.138264 -0.465730
2        2  a  0.647689  0.241962
3        3  a  1.523030 -1.913280
4        4  a -0.234153 -1.724918
5        5  a -0.234137 -0.562288
6        6  a  1.579213 -1.012831
7        7  a  0.767435  0.314247
8        8  a -0.469474 -0.908024
9        9  a  0.542560 -1.412304
0        0  b  1.465649 -0.601707
1        1  b -0.225776  1.852278
2        2  b  0.067528 -0.013497
3        3  b -1.424748 -1.057711
4        4  b -0.544383  0.822545
5        5  b  0.110923 -1.220844
6        6  b -1.150994  0.208864
7        7  b  0.375698 -1.959670
8        8  b -0.600639 -1.328186
9        9  b -0.291694  0.196861

Мои фактические данные имеют 6 различных переменных, 45 станций и более 22 000 идентификаторов.

Теперь я хочу преобразовать dataframe таким образом, чтобы у меня был столбец для каждой переменной на каждой станции и имел идентификатор в качестве индекса. Поэтому я хочу получить следующее:

      Var1_0    Var1_1    Var1_2    ...       Var2_7    Var2_8    Var2_9
ID                                  ...                                 
a   0.496714 -0.138264  0.647689    ...     0.314247 -0.908024 -1.412304
b   1.465649 -0.225776  0.067528    ...    -1.959670 -1.328186  0.196861

Я попробовал это:

def test_func(x, IQ):
    col = IQ + '_' + str(x['Station'])
    out = {col: x[IQ]}
    return pd.Series(out)

def transformIQ(df, IQs):
    for i, iq in enumerate(IQs):
        if i==0:
            df_new = df.apply(lambda x: test_func(x, iq), axis=1)
        else:
            df_tmp = df.apply(lambda x: test_func(x, iq), axis=1)
            df_new = pd.concat([df_new, df_tmp], axis=1)

    return df_new

IQs = ['Var1', 'Var2']
df3 = transformIQ(df, IQs)

df4 = pd.concat([df, df3], axis=1)    

dfpivot = df4.pivot_table(index='ID').drop(['Station', 'Var1', 'Var2'], axis=1)

Это дает мне фреймворк данных, как будто я хочу его, но, как я уже говорил, мои фактические данные содержат более 1 000 000 строк, и этот подход не работает. Есть ли лучший/более простой способ сделать это, который может обрабатывать более 1 000 000 строк?

Теги:
pandas

1 ответ

1
Лучший ответ

Использовать stack с unstack:

df = df.set_index(['ID','Station']).stack().unstack([2,1]).sort_index(axis=1)
#flatten columns, 3.6+
df.columns = [f'{i}_{j}' for i, j in df.columns]
#bellow 3.6
#df.columns = ['{}_{}'.format(i, j) for i, j in df.columns]
print (df)
      Var1_0    Var1_1    Var1_2    Var1_3    Var1_4    Var1_5    Var1_6  \
ID                                                                         
a   0.496714 -0.138264  0.647689  1.523030 -0.234153 -0.234137  1.579213   
b   1.465649 -0.225776  0.067528 -1.424748 -0.544383  0.110923 -1.150994   

      Var1_7    Var1_8    Var1_9    Var2_0    Var2_1    Var2_2    Var2_3  \
ID                                                                         
a   0.767435 -0.469474  0.542560 -0.463418 -0.465730  0.241962 -1.913280   
b   0.375698 -0.600639 -0.291694 -0.601707  1.852278 -0.013497 -1.057711   

      Var2_4    Var2_5    Var2_6    Var2_7    Var2_8    Var2_9  
ID                                                              
a  -1.724918 -0.562288 -1.012831  0.314247 -0.908024 -1.412304  
b   0.822545 -1.220844  0.208864 -1.959670 -1.328186  0.196861  
  • 0
    Круто, спасибо большое!
  • 0
    @petetheat - Добро пожаловать!
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню