Реструктуризация pandas кадра данных на основе количества столбцов - PullRequest
2 голосов
/ 04 марта 2020

У меня есть следующий pandas фрейм данных.

ID   Col1   Col2   Col3   Col4   Col5   Col6   Col7   Col8   Col9
1     A      B       C      A     B      C      A      B      C
2     D      E       F      D     E      F      D      E      F 

Я хотел бы получить следующую таблицу путем реструктуризации каждых трехколоночных значений.

ID   Col_1   Col_2   Col_3
1      A       B       C
       A       B       C
       A       B       C

2      D       E       F
       D       E       F
       D       E       F

ИЛИ

ID   Col_1   Col_2   Col_3
1      A       B       C
1      A       B       C
1      A       B       C
2      D       E       F
2      D       E       F
2      D       E       F

Есть ли эффективный способ сделать это? Я пытался найти подобные примеры здесь, в сообществе StackOverflow, но не смог. Если у вас есть, вы можете указать мне.

Любая помощь приветствуется!

Ответы [ 3 ]

6 голосов
/ 04 марта 2020

Вы можете использовать DataFrame.stack с MultiIndex по всем столбцам без ID, созданным целочисленным делением и делением по модулю:

df = df.set_index('ID')
c = np.arange(len(df.columns))
df.columns = [c // 3, c % 3]
df1 = (df.stack()
         .reset_index(level=1, drop=True)
         .rename(columns= lambda x: f'Col_{x+1}')
         .reset_index())
print (df1)
   ID Col_1 Col_2 Col_3
0   1     A     A     A
1   1     B     B     B
2   1     C     C     C
3   2     D     D     D
4   2     E     E     E
5   2     F     F     F
2 голосов
/ 04 марта 2020

Вот один с apply и np.reshape:

f = lambda x: pd.DataFrame(np.reshape(x.to_numpy(),(-1,3))).add_prefix('Col_')
df.groupby('ID').apply(f).reset_index('ID')

   ID Col_0 Col_1 Col_2
0   1     A     B     C
1   1     A     B     C
2   1     A     B     C
3   2     D     E     F
4   2     D     E     F
5   2     D     E     F
2 голосов
/ 04 марта 2020

Я не уверен насчет эффективности, но она работает:

k = 3  # every k column
pd.DataFrame([df.values[:,[n,n+k,n+k]].flatten() for n in range(k)]).T

   0  1  2
0  A  B  C
1  A  B  C
2  A  B  C
3  D  E  F
4  D  E  F
5  D  E  F
...