2016-07-31 36 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