2016-07-31 13 views
0

我有一对夫妇,所有具有相同的第一列(X)文件,和相同的列名(XBC),但第二和第三列是不同的值。合并文件到蟒蛇多指标数据帧,最后导出为TXT

X | B | C 
----------- 
a 0 2 
b 4 9 
... 
z 3 0 

我想所有这些表合并成一个大的数据帧,但增加了每个部分是通过自己的索引访问,例如基于文件。例如。 df['f1']['B']将是[0, 4..., 3]。最终结果将如下所示。

| f1 | f1 | f2 | f2 
X | B | C | B | C 
----------------------- 
a 0 2 3 2 
b 4 9 1 2 
...   
z 3 0 9 8 

这是我到目前为止的代码

import pandas as pd 
import numpy as np 
import regex as re 

dir = 'directory' 
path = os.path.abspath(os.path.join(os.getcwd(), dir)) 
# List all files in folder 
filenames = [name for name in os.listdir(path) if re.match(".*\.txt$", name)] 

r_coln = re.compile(r"\.txt$") 

frames = [] 

for i in range(len(filenames)): 
    filename = filenames[i] 
    coln = r_coln.sub("", filename) 
    if (i == 0): 
     # Subtract the first column which is identical for all frames 
     first_frame = pd.read_csv(os.path.join(path, filename), usecols=[0], sep="\t", names=[''], header=None) 
     frames.append(first_frame) 

    # Get frame with a new header 
    frames.append(pd.read_csv(os.path.join(path, filename), usecols=[1, 2], sep="\t", names=[coln, ''], header=None)) 

# Combine all frames 
df = pd.concat(frames, axis=1) 

这工作,因为所产生的数据帧确实像我张贴上面异常的例子,我只有一个“顶”标题每个文件。使用names=[coln, coln]而不是names=[coln, '']导致两列中的一列掉线(我不知道为什么)。但是,它不是多索引的。换句话说,我不能访问df['f1']['B'],因为它返回错误KeyError: 'B'。我正在寻找一种方法来实现这一点。可以通过在读入循环后转换结果df,或者通过更改循环内的某些东西来完成。

最后,我还想将此数据框导出为制表符分隔的文本文件。

+1

您可以在'pd.concat'中使用'keys'参数。它会自动创建一个多重索引并为其添加一个由传递的键组成的较高级别。 ('names'为关卡添加名称。)另外,您可能希望首先将'X'设置为索引 - 无论是使用.set_index方法还是将'index_col'参数设置为'pd.read_csv'。 – ptrj

回答

0

编辑 - 为@ptrj添加单行,信用。

df = pd.concat([df1.set_index('X'),df2.set_index('X')],axis=1,keys = ['F1','F2']) 

In []: df 
Out[]: 
     F1 F2 
    B C B C 
X 
a 0 2 0 4 
b 4 9 8 18 
z 3 0 6 0 

替代解决方案:

您可以从阵列定义一个多指标。

让我们从两个示例DataFrame开始。

df1 = pd.DataFrame({'B': {0: 0, 1: 4, 2: 3}, 
        'C': {0: 2, 1: 9, 2: 0}, 
        'X': {0: 'a', 1: 'b', 2: 'z'}}) 

df2 = pd.DataFrame({'B': {0: 0, 1: 8, 2: 6}, 
        'C': {0: 4, 1: 18, 2: 0}, 
        'X': {0: 'a', 1: 'b', 2: 'z'}}) 

# Merge the DataFrames 
merged = df1.merge(df2,on='X').set_index('X') 

# Create a MultiIndex 
arrays = [['F1','F1','F2','F2'], ['B','C','B','C']] 
columns = pd.MultiIndex.from_arrays(arrays, names=['level1', 'level2']) 

# Create your DataFrame  

df = pd.DataFrame(data=merged.as_matrix(), 
        columns=columns, 
        index = df1['X']) 

df现在看起来像:

level1 F1  F2 
level2 B C B C 
    X    
    a 0 2 0 4 
    b 4 9 8 18 
    z 3 0 6 0 

现在,你可以索引它使用df['F1']

level2 B C 
    X   
    a 0 2 
    b 4 9 
    z 3 0 

或者df['F1']['B'],它给你:

0 0 
1 4 
2 3 

编辑:@Bram Vanroy extended this solution与多个DataFrames一起使用。

+0

解决了您制作的一些错别字后,它可以正常工作。但是,X列仍然可见。 –

+0

@BramVanroy - 道歉!我做了一些改变,你可以再试一次吗? – user666

+0

[但是,X列仍然可见]尝试.......列表(df ['F1'] ['B']。值) – Merlin