从长到宽的窗户

2024-04-19 20:21:05 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试通过将行数据的“窗口”转换为列数据来重塑数据帧。例如,如果窗口大小为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

这很棘手,因为旧数据帧中的单元格在生成的数据帧中可能没有唯一索引。你知道吗

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


Tags: 数据a2a1b2a3b1a4b3
1条回答
网友
1楼 · 发布于 2024-04-19 20:21:05

您可以将窗口大小为2的操作视为将数据帧向上移动一行,将其与原始数据帧水平连接,最后重新排序。因此,无需对行进行迭代,就可以这样做:

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

相关问题 更多 >