拥有如下数据框:
import pandas
df = pandas.DataFrame({'a': [1, 2, 3], 'b': [9, 8, 7], 'c': [4, 5, 6]})
df
我希望有一个数据框:
['a', 'b']
。这个专栏的名字,我不在乎。a
或b
列的旧值的列,具体取决于['a', 'b']
因子。这个专栏的名字,我不在乎。c
列值和名称(实际数据框中有几列我想保留)。这是我想要得到的一个例子:
df['name_a'] = 'a'
df['name_b'] = 'b'
c0 = pandas.concat([df['name_a'], df['name_b']])
c1 = pandas.concat([df['a'], df['b']])
c2 = pandas.concat([df['c'], df['c']])
newdf = pandas.concat([c0, c1, c2], axis=1)
newdf
有没有更好的方法来达到相同的效果?我觉得这样很难看。也许我缺少一个pandas
函数,使代码更清晰,更易于理解?
答案 0 :(得分:1)
我认为你需要melt
:
print (pd.melt(df,id_vars='c', var_name='0', value_name='1'))
c 0 1
0 4 a 1
1 5 a 2
2 6 a 3
3 4 b 9
4 5 b 8
5 6 b 7
stack
与sort_values
的另一种解决方案:
df1 = df.set_index('c').stack().reset_index().sort_values('level_1')
df1.columns = ['c', '0','1']
print (df1)
c 0 1
0 4 a 1
2 5 a 2
4 6 a 3
1 4 b 9
3 5 b 8
5 6 b 7
更一般的解决方案 - 使用list comprehension
过滤所有非a
和b
到变量cols
的列:
cols = [col for col in df.columns if col not in ['a','b']]
print (cols)
['c']
print (pd.melt(df,id_vars=cols, var_name='0', value_name='1'))
c 0 1
0 4 a 1
1 5 a 2
2 6 a 3
3 4 b 9
4 5 b 8
5 6 b 7
示例添加了另一列g
:
df = pd.DataFrame({'a': [1, 2, 3],
'b': [9, 8, 7],
'c': [4, 5, 6],
'g': [0, 1, 7]})
print (df)
a b c g
0 1 9 4 0
1 2 8 5 1
2 3 7 6 7
cols = [col for col in df.columns if col not in ['a','b']]
print (cols)
['c', 'g']
使用numpy.setdiff1d
加快解决方案:
cols = np.setdiff1d(df.columns, ['a','b']).tolist()
print (cols)
['c', 'g']
print (pd.melt(df,id_vars=cols, var_name='0', value_name='1'))
c g 0 1
0 4 0 a 1
1 5 1 a 2
2 6 7 a 3
3 4 0 b 9
4 5 1 b 8
5 6 7 b 7