如何从已有Pandas Series的子数组优雅生成指定结构的DataFrame?
优雅实现从Pandas Series滑动子数组生成DataFrame(无循环)
嘿,这个需求很常见,完全不用写循环就能搞定!我给你两种优雅的实现方式,按需选择就行:
方法一:用Pandas内置的shift方法(直观易读)
这种方法逻辑清晰,新手也能一眼看懂,适合处理中小型数据集:
import pandas as pd # 输入Series s = pd.Series([1,2,3,4,5,6]) # 定义窗口大小(这里是3列,所以窗口为3) window_size = 3 # 拼接移位后的Series,去掉空值,重命名列 df = pd.concat( [s.shift(-i) for i in range(window_size)], axis=1 ).dropna().astype(int) df.columns = ['x', 'y', 'z'] print(df)
原理说明:
s.shift(-i)会把原Series向右偏移i位,比如shift(-1)就得到[2,3,4,5,6,NaN]- 把偏移0、1、2位的三个Series按列拼接,最后用
dropna()去掉末尾带NaN的行,再转成整数类型就得到目标结构了。
方法二:用Numpy的as_strided(性能拉满)
如果你的数据集很大,想要极致性能,推荐用这个方法——它直接操作内存视图,几乎没有额外的内存开销:
import pandas as pd import numpy as np s = pd.Series([1,2,3,4,5,6]) window_size = 3 # 转成Numpy数组 arr = s.to_numpy() # 生成滑动窗口视图 strided_arr = np.lib.stride_tricks.as_strided( arr, shape=(len(arr) - window_size + 1, window_size), # 输出的行数和列数 strides=(arr.strides[0], arr.strides[0]) # 行和列的步长设置 ) # 转成DataFrame并命名列 df = pd.DataFrame(strided_arr, columns=['x', 'y', 'z']) print(df)
注意事项:
as_strided是直接操作内存的高级方法,一定要确保shape参数计算正确(行数=原长度-窗口大小+1),否则会读取到内存里的无效数据。- 这个方法的速度比
shift快很多,数据量越大优势越明显。
两种方法运行后都会得到你想要的结果:
x y z 0 1 2 3 1 2 3 4 2 3 4 5 3 4 5 6
内容的提问来源于stack exchange,提问作者Roman Kazmin
相关产品推荐
相关产品推荐

