2015-04-23 68 views
0

我试图通过将行数据的'窗口'转换为列数据来重塑数据框。例如,为2的窗口大小,给出的数据帧:大熊猫长窗宽

A B 
0 a1 b1 
1 a2 b2 
2 a3 b3 
3 a4 b4 

我想以产生数据帧:

A1 A2 B1 B2 
0 a1 a2 b1 b2 
1 a2 a3 b2 b3 
2 a3 a4 b3 b4 

这是棘手的,因为在旧数据帧的小区在生成的数据框中可能没有唯一索引。

我当然可以做一些复杂的事情,比如迭代旧数据框中的行,计算新单元格的位置,并简单地复制数据。但我想要一个更简单的解决方案...

回答

0

您可以查看窗口大小为2的操作,将DataFrame向上移动一行,将其与原始DataFrame水平连接,最后重新排序。因此,如果不遍历行是可以做到这样的:

res = df.merge(df.shift(-1), left_index=True, right_index=True).iloc[:-1] 
res.columns = ['A1', 'B1', 'A2', 'B2'] 
res = res[['A1', 'A2', 'B1', 'B2']] 
print res 

输出:

A1 A2 B1 B2 
0 a1 a2 b1 b2 
1 a2 a3 b2 b3 
2 a3 a4 b3 b4 

这可以推广到任意数据帧和窗口大小:

def rolling(df, window_size=2): 
    dfs = [df] 
    for i in range(1, window_size): 
     dfs.append(df.shift(-i)) 
    res = pd.concat(dfs, axis=1).iloc[:-(window_size-1)] 
    colnames = [c + str(i) for i in range(1, window_size+1) for c in df.columns] 
    reorder = [c + str(i) for c in df.columns for i in range(1, window_size+1)] 
    res.columns = colnames 
    return res[reorder] 

print rolling(df, 3) 

输出:

A1 A2 A3 B1 B2 B3 
0 a1 a2 a3 b1 b2 b3 
1 a2 a3 a4 b2 b3 b4 
+0

非常好!经过进一步的反思,我的问题实际上需要将窗口函数应用到原始数据框中的每一行,而将NaN留在下面没有值的地方。这可以简单地通过除去串联结果上的.iloc调用来实现。 –