将大量DataFrame合并在一起,没有循环,也没有使用concat

时间:2014-05-17 00:31:45

标签: python pandas

我有> 1000个DataFrames,每个都有> 20K行和几列,需要通过某个公共列进行合并,这个想法可以用这个来说明:

data1=pd.DataFrame({'name':['a','c','e'], 'value':[1,3,4]})
data2=pd.DataFrame({'name':['a','d','e'], 'value':[3,3,4]})
data3=pd.DataFrame({'name':['d','e','f'], 'value':[1,3,5]})
data4=pd.DataFrame({'name':['d','f','g'], 'value':[0,3,4]})
#some or them may have more or less columns that the others:
#data5=pd.DataFrame({'name':['d','f','g'], 'value':[0,3,4], 'score':[1,3,4]})

final_data=data1
for i, v in enumerate([data2, data3, data4]):
    if i==0:
        final_data=pd.merge(final_data, v, how='outer', left_on='name', 
                            right_on='name', suffixes=('_0', '_%s'%(i+1)))
        #in real case right_on may be = columns other than 'name' 
        #dependents on the dataframe, but this requirement can be 
        #ignored in this minimal example. 
    else:
        final_data=pd.merge(final_data, v, how='outer', left_on='name', 
                            right_on='name', suffixes=('', '_%s'%(i+1)))   

结果:

  name  value_0  value_1  value  value_3
0    a        1        3    NaN      NaN
1    c        3      NaN    NaN      NaN
2    e        4        4      3      NaN
3    d      NaN        3      1        0
4    f      NaN      NaN      5        3
5    g      NaN      NaN    NaN        4

[6 rows x 5 columns]

它有效,但无论如何这可以在没有循环的情况下完成?

,为什么倒数第二列的列名不是value_2


P.S。 我知道在这个最小的例子中,结果也可以通过以下方式实现:

pd.concat([item.set_index('name') for item in [data1, data2, data3, data4]], axis=1) 

但实际情况是由于数据帧的构建方式以及存储在索引列中的信息,如果没有额外的技巧,这不是理想的解决方案。所以,我们不要考虑这条路线。

1 个答案:

答案 0 :(得分:1)

合并它是否有意义呢?小组出了什么问题?

> data = [data1, data2, data3, data4]
> p = pd.Panel(dict(zip(map(str, range(len(data))), data)))
> p.to_frame().T
major    0          1          2      
minor name value name value name value
0        a     1    c     3    e     4
1        a     3    d     3    e     4
2        d     1    e     3    f     5
3        d     0    f     3    g     4

# and just for kicks
> p.transpose(2, 0, 1).to_frame().reset_index().pivot_table(values='value', rows='name', cols='major')
major   0   1   2   3
name                 
a       1   3 NaN NaN
c       3 NaN NaN NaN
d     NaN   3   1   0
e       4   4   3 NaN
f     NaN NaN   5   3
g     NaN NaN NaN   4