合并DataFrame

时间:2016-11-02 12:26:26

标签: python pandas

拥有如下数据框:

import pandas

df = pandas.DataFrame({'a': [1, 2, 3], 'b': [9, 8, 7], 'c': [4, 5, 6]})
df

enter image description here

我希望有一个数据框:

  • 因子/类别列['a', 'b']。这个专栏的名字,我不在乎。
  • 具有ab列的旧值的列,具体取决于['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

enter image description here

有没有更好的方法来达到相同的效果?我觉得这样很难看。也许我缺少一个pandas函数,使代码更清晰,更易于理解?

1 个答案:

答案 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

stacksort_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过滤所有非ab到变量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