Добавить столбец-метку в фрейм данных

#python #pandas #dataframe #pandas-melt

Вопрос:

Например, у меня есть два фрейма данных

 df1:

0    1    2    3
a    1    2    3    4
b   10   20   30   40
c  100  200  300  400
------------------

df2:

   0
0  x
1  y
2  z
 

Теперь я хочу объединить оба типа:

 df_new:

   value label
0      1     x
1      2     x
2      3     x
3      4     x
0     10     y
1     20     y
2     30     y
3     40     y
0    100     z
1    200     z
2    300     z
3    400     z
 

Я написал действительно неудобный код, например:

 df_new=pd.DataFrame()

for i,j in zip(df1.index, df2.index):
    x=df1.loc[i]
    y=df2.loc[j]
    

    label=np.full(x.shape[0],y)
    
    df=pd.DataFrame({'value':x,'label':label})
    df_new=pd.concat([df_new,df],axis=0)
    
print(df_new)
 

Но я могу себе представить, что есть функция pandas, такая как pd.melt или что-то, что может сделать это лучше для большего масштаба.

Комментарии:

1. Ответ был отредактирован.

Ответ №1:

Если существует одинаковая длина обоих фреймов данных, возможно создание индекса в df1 столбце 0 по df2 и изменение формы по DataFrame.stack , последнее требует некоторой обработки данных:

 df = (df1.set_index(df2[0])
         .stack()
         .reset_index(level=1, drop=True)
         .rename_axis('lab')
         .reset_index(name='val')[['val','lab']])


print (df)
    val lab
0     1   x
1     2   x
2     3   x
3     4   x
4    10   y
5    20   y
6    30   y
7    40   y
8   100   z
9   200   z
10  300   z
11  400   z
 

Решение с DataFrame.melt помощью и добавление второго df к первому с помощью DataFrame.join :

 df = (df1.reset_index(drop=True)
         .join(df2.add_prefix('label'))
         .melt(['label0', 'label1'], ignore_index=False)
         .sort_index(ignore_index=True)
         .drop('variable', axis=1)[['value','label0','label1']]
         )
print (df)
    value label0 label1
0       1      x     xx
1       2      x     xx
2       3      x     xx
3       4      x     xx
4      10      y     yy
5      20      y     yy
6      30      y     yy
7      40      y     yy
8     100      z     zz
9     200      z     zz
10    300      z     zz
11    400      z     zz