在pandas中合并两个文件,一个列和一个公共索引

时间:2013-09-20 03:07:37

标签: python csv pandas

我有10个带有两列的.csv文件。例如

file1.csv

Bact1,[1821932:1822487](+)
Bact2,[555760:556294](+)
Bact3,[2901866:2902424](-)
Bact4,[1104980:1105544](+)

file2.csv

Bact1,[1973928:1975194](-)
Bact2,[972152:973499](+)
Bact3,[3001035:3002739](-)
Bact4,[3331158:3332481](+)
Bact5,[712517:713771](+)
Bact5,[1376120:1377386](-)

file3.csv

Bact6,[4045708:4047781](+)

依此类推至file10.csv Bact1代表细菌种类,包括符号在内的所有数字代表基因的位置。每个文件代表一个不同的基因,并且有像file2.csv

那样的重复文件

我想合并这些文件,以便我有类似的东西

Bact1    [1821932:1822487](+)    [1973928:1975194](-)    NaN
Bact2    [555760:556294](+)      [972152:973499](+)      NaN
Bact3    [2901866:2902424](-)    [3001035:3002739](-)    NaN
Bact4    [1104980:1105544](+)    [3331158:3332481](+)    NaN
Bact5    NaN                     [712517:713771](+)      NaN     
Bact5    NaN                        [1376120:1377386](-)    NaN
Bact6    NaN                     NaN                     [4045708:4047781](+)

我曾尝试在python中使用pandas包,但似乎大部分功能都是为了合并两个数据帧,不超过两个,或者我错过了什么。

我上周刚刚开始在python中编程(我通常使用R),所以陷入可能或至少是一件简单的事情。

现在我正在使用:

    for x in range(1,10):
        df[x]=pandas.read_csv("file%s.csv" % (x),header=None,index_col=[0])
        df[x].columns=['gene%s' % (x)]
   dfjoin={}
   dfjoin=df[1].join([df[2],df[3],df[4],df[5],df[6],df[7],df[8],df[9],df[10]])

结果:

0                          gene1           gene2             gene3                 
Starkeya-novella-DSM-506     NaN     [728886:730173](+)  [731445:732615](+)     
Starkeya-novella-DSM-506     NaN     [728886:730173](+)  [9662:10994](+)    
Starkeya-novella-DSM-506     NaN     [728886:730173](+)  [9662:10994](+)     
Starkeya-novella-DSM-506     NaN     [728886:730173](+)  [9662:10994](+) 

参见gene2和gene3,它复制了重复的结果。

2 个答案:

答案 0 :(得分:2)

假设您已按照以下方式在DataFrame中阅读这些内容:

In [11]: df1 = pd.read_csv('file1.csv', sep=',', header=None, index_col=[0], names=['bact', 'file1'])

In [12]: df1
Out[12]: 
                      file1
bact
Bact1  [1821932:1822487](+)
Bact2    [555760:556294](+)
Bact3  [2901866:2902424](-)
Bact4  [1104980:1105544](+)

然后你可以简单地join

In [21]: df1.join([df2, df3])
Out[21]: 
                      file1                 file2                 file3
bact
Bact1  [1821932:1822487](+)  [1973928:1975194](-)                   NaN
Bact2    [555760:556294](+)    [972152:973499](+)                   NaN
Bact3  [2901866:2902424](-)  [3001035:3002739](-)                   NaN
Bact4  [1104980:1105544](+)  [3331158:3332481](+)                   NaN
Bact5                   NaN    [712517:713771](+)                   NaN
Bact5                   NaN  [1376120:1377386](-)                   NaN
Bact6                   NaN                   NaN  [4045708:4047781](+)

答案 1 :(得分:1)

我稍微更改了您的示例数据,这是代码:

import pandas as pd
import io

data = {
"file1":"""Bact1,[1821932:1822487](+)
Bact2,[555760:556294](+)
Bact3,[2901866:2902424](-)
Bact4,[1104980:1105544](+)
Bact5,[1104981:1105544](+)
Bact5,[1104982:1105544](+)""",

"file2":"""Bact1,[1973928:1975194](-)
Bact2,[972152:973499](+)
Bact3,[3001035:3002739](-)
Bact4,[3331158:3332481](+)
Bact5,[712517:713771](+)
Bact5,[1376120:1377386](-)
Bact5,[1376121:1377386](-)""",

"file3":"""Bact4,[3331150:3332481](+)
Bact6,[4045708:4047781](+)"""}

def read_file(f):
    s = pd.read_csv(f, header=None, index_col=0, squeeze=True)
    return s.groupby(s.index).apply(lambda s:pd.Series(s.values))

series = {key:read_file(io.StringIO(unicode(text)))
          for key, text in data.items()}

print pd.concat(series, axis=1)

输出:

                        file1                 file2                 file3
0                                                                        
Bact1 0  [1821932:1822487](+)  [1973928:1975194](-)                   NaN
Bact2 0    [555760:556294](+)    [972152:973499](+)                   NaN
Bact3 0  [2901866:2902424](-)  [3001035:3002739](-)                   NaN
Bact4 0  [1104980:1105544](+)  [3331158:3332481](+)  [3331150:3332481](+)
Bact5 0  [1104981:1105544](+)    [712517:713771](+)                   NaN
      1  [1104982:1105544](+)  [1376120:1377386](-)                   NaN
      2                   NaN  [1376121:1377386](-)                   NaN
Bact6 0                   NaN                   NaN  [4045708:4047781](+)