2015-12-30 16 views
1

我期望展平一列DataFrame,其中有多列(下面爲['a', 'b', 'c'])列,每列n列(下圖:n = 2)。還有一些不需要被壓平的停滯數據(下面:['Misc','Year'])。下面是一個例子DataFramePython展平多列所有n長度的數據框

df = pd.DataFrame({ 
'Misc': ['A', 'R', 'B'], 
'Year': [1991, 1992, 1993], 
'a1': [10, 20, 30], 
'a2': [40, 50, 60], 
'b1': ['h', 'i', 'j'], 
'b2': ['k', 'l', 'm'], 
'c1': [4.1, 4.2, 4.3], 
'c2': [4.4, 4.5, 4.6] }) 

產生如下:

In [244]: df 
Out[244]: 
    Misc Year a1 a2 b1 b2 c1 c2 
0 A 1991 10 40 h k 4.1 4.4 
1 R 1992 20 50 i l 4.2 4.5 
2 B 1993 30 60 j m 4.3 4.6 

我所要的輸出是:

In [4]: df1 
Out[4]: 
    Misc Year a b c 
0 A 1991 10 h 4.1 
1 A 1991 40 k 4.4 
2 R 1992 20 i 4.2 
3 R 1992 50 l 4.5 
4 B 1993 30 j 4.3 
5 B 1993 60 m 4.6 

所以[ai, bi, ci]移動到一個單一的row同時保持[雜項,年]。我正在處理成千上萬的行數據集,因此性能是一個大問題。我目前正在循環每行來分隔它們,但希望有一個更好的扁平化python函數。我已經看到了熊貓的「融化」功能,但它似乎只適用於有單一羣體的情況。

最終,我想創建一個幫助函數,它可以接受任意數量的「組」列,「停滯」列和「n」值。

我目前使用的是熊貓,但也對其他解決方案開放。謝謝您的幫助! :)

回答

0

怎麼樣這個問題:

In [11]: df1 = df[["Misc", "Year"] + [c for c in df.columns if c[-1] == "1"]] 

In [12]: df1 = df1.rename(columns=lambda x: x[:-1] if x[-1] == "1" else x) 

In [13]: df1 
Out[13]: 
    Misc Year a b c 
0 A 1991 10 h 4.1 
1 R 1992 20 i 4.2 
2 B 1993 30 j 4.3 

In [14]: df2 = df[["Misc", "Year"] + [c for c in df.columns if c[-1] == "2"]] 

In [15]: df2 = df2.rename(columns=lambda x: x[:-1] if x[-1] == "2" else x) 

In [16]: pd.concat([df1, df2]) 
Out[16]: 
    Misc Year a b c 
0 A 1991 10 h 4.1 
1 R 1992 20 i 4.2 
2 B 1993 30 j 4.3 
0 A 1991 40 k 4.4 
1 R 1992 50 l 4.5 
2 B 1993 60 m 4.6 

你能做到這一點的理解,或功能,更普遍:

In [21]: pd.concat([df[["Misc", "Year"] + [c for c in df.columns if c[-1] == str(i)]] 
        .rename(columns=lambda x: x[:-1] if x[-1] == str(i) else x) 
        for i in range(1, 3)]) 
Out[21]: 
    Misc Year a b c 
0 A 1991 10 h 4.1 
1 R 1992 20 i 4.2 
2 B 1993 30 j 4.3 
0 A 1991 40 k 4.4 
1 R 1992 50 l 4.5 
2 B 1993 60 m 4.6 

如果要勉強維持一些性能,會想要在numpy中做這個連接,然後重複索引(雖然我不相信這是值得你獲得的小增益)。

+0

謝謝安迪!如果我想保留'第i'列索引怎麼辦?是否可以在concat函數中創建一個全新的列,比如'N_index',並將其賦值爲str(i)的值? – kolze100

+0

@ kolze100 IIUC我會(懶洋洋地)用'.sort_index()',然後'.reset_index()'做這個。從某種意義上說,你想要的索引不是真的來自任何地方,我不認爲它可以在concat中完成。 –

+0

嗯,我實際上打算在它上面執行一些邏輯。我想用「年」欄和「ith」號碼來獲得年份 - 月份組合。例如:i = 2年= 1992年將被置於'日期'欄作爲'Feb-1992'。有什麼建議麼? – kolze100

0

這不是一個重塑/熔化類型函數的典型應用,所以你可能會不得不推出自己的。下面是應該是比較高性能的解決方案提供(# groups)*n並不太大:

取2個dataframes,一個與[Misc, Year, a1, b1, c1]列,其他與[Misc, Year, a2, b2, c2]和垂直方向將它們連接起來。

這可以自動執行任意數量的組和n值,前提是列名具有統一的約定,如<letter><number>,如您的示例中所示。您必須對列名執行一些正則表達式分析,以確定每個數據框中的哪些列彙集在一起​​。

在所有這些數據框中創建一個名爲subframes的列表,並將它們與pd.concat(subframes)連接在一起。

相關問題