2016-04-18 2 views
6

у меня есть кадр данных, как этотПередача столбцов строк на питон панд

id a b c 
101 0 3 0 
102 2 0 5 
103 0 1 4 

и я хочу что-то вроде этого

id letter num 
101  a  0 
101  b  3 
101  c  0 
102  a  2 
102  b  0 
102  c  5 
103  a  0 
103  b  1 
103  c  4 

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

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

ответ

6

Вы можете melt, а затем сортировать:

>>> pd.melt(df, id_vars='id', value_vars=['a','b','c'], 
      var_name='letter', value_name='num').sort_values('id') 
    id letter num 
0 101  a 0 
3 101  b 3 
6 101  c 0 
1 102  a 2 
4 102  b 0 
7 102  c 5 
2 103  a 0 
5 103  b 1 
8 103  c 4 

Если вы хотите сбросить индекс, вы всегда можете использовать .reset_index(drop=True) на возвращаемом DataFrame.

+0

Это решение лучше, чем мой ужасный цикл, я бы просто добавить в _value_vars_ вместо [ 'A', 'B', 'C'] -> ** список (df.columns [1:]) **, поскольку у меня было намного больше столбцов, чем просто a, b, c –

0

Вы, вероятно, хотите сделать что-то вдоль линий

df2 = df.stack().reset_index(1) 

переименовать столбцы

df.stack() производит серию с индексом многоуровневом:

In [5]: df.stack() 
Out[5]: 
id  
101 a 0 
    b 3 
    c 0 
102 a 2 
    b 0 
    c 5 
103 a 0 
    b 1 
    c 4 
dtype: int64 

Затем вы хотите разбить этот многоуровневый индекс на свои собственные столбцы. Используя , в качестве индекса указывается столбец id. Но обратите внимание, что другие столбцы имеют неправильные имена (соответствующие их прежним уровням в многоуровневом индексе).

In [6]: df.stack().reset_index(1) 
Out[6]: 
    level_1 0 
id    
101  a 0 
101  b 3 
101  c 0 
102  a 2 
102  b 0 
102  c 5 
103  a 0 
103  b 1 
103  c 4 

Так переименовать их:

In [8]: df2.columns = ['letter', 'num'] 

In [9]: df2 
Out[9]: 
    letter num 
id    
101  a 0 
101  b 3 
101  c 0 
102  a 2 
102  b 0 
102  c 5 
103  a 0 
103  b 1 
103  c 4 
0

Вы можете использовать ravel, чтобы изменить значения обратно в один столбец.

df = pd.DataFrame({'id': [101, 102, 103], 
        'a': [0, 2, 0], 
        'b': [3, 0, 1], 
        'c': [0, 5, 4]})[['id', 'a', 'b', 'c']] 

>>> pd.DataFrame({'letter': df.columns[1:].tolist() * len(df), 
        'num': df.iloc[:, 1:].values.ravel()}) 
    letter num 
0  a 0 
1  b 3 
2  c 0 
3  a 2 
4  b 0 
5  c 5 
6  a 0 
7  b 1 
8  c 4 
Смежные вопросы