2015-12-30 14 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)连接在一起。

相关问题