如何将Pandas DataFrame转为带表头与数据类型的标准Numpy数组?
搞定Pandas转Numpy的问题:保留类型、表头,还要标准数组
嗨,我来帮你解决这个转换的问题!你说的情况我太懂了——Pandas虽然好用,但大数据量下确实慢,换成Numpy跑计算能快不少,而且还得保住数据类型和表头方便查,同时要是标准的Numpy数组(shape得显示列数才行)。
第一步:先拿到标准的二维Numpy数组
其实根本不用搞什么列表推导式转元组,直接用Pandas自带的to_numpy()方法就行,这玩意儿直接给你生成标准的二维数组,shape会老老实实显示行数和列数,数据类型也能完美保留:
import pandas as pd import numpy as np from numpy.random import randn # 先建你的测试DataFrame df = pd.DataFrame(randn(10,3), columns=['Acol','Ccol','Bcol']) # 一键转换 arr = df.to_numpy() print(arr.shape) # 输出 (10, 3),行列数清清楚楚 print(arr.dtype) # 原DataFrame的float64类型完全保留
要是你想强制指定数据类型(比如转成float32省内存),直接加个dtype参数就行:
arr = df.to_numpy(dtype=np.float32)
第二步:怎么保留表头方便查阅?
Numpy数组本身不像Pandas那样自带表头属性,但有俩简单办法解决:
1. 表头单独存个变量(最推荐,不影响速度)
就把列名单独存成列表或者Numpy数组,用的时候对应着看就行,完全不影响Numpy数组的计算效率:
# 存成普通列表 headers = df.columns.tolist() # 得到 ['Acol','Ccol','Bcol'] # 或者转成Numpy数组 headers_np = df.columns.to_numpy()
比如想知道第0列对应啥表头,直接看headers[0]就行,简单粗暴还不拖慢计算。
2. 用结构化数组(表头和数据绑定)
要是你想把表头和数据绑在一起,不用单独查变量,可以用Numpy的结构化数组。这种数组每个元素是带字段名的结构,能直接用表头名称取列,不过注意它的shape是行数(一维数组),但计算速度会比纯二维数组稍慢一点:
# 生成结构化数组,index=False是去掉Pandas的行索引 struct_arr = df.to_records(index=False) print(struct_arr.shape) # 输出 (10,),但每个元素包含3个字段 print(struct_arr.dtype) # 能看到字段名和类型:[('Acol', '<f8'), ('Ccol', '<f8'), ('Bcol', '<f8')] # 直接用表头取列,和Pandas一样方便 print(struct_arr['Acol'])
为啥你之前的代码不行?
你之前用[tuple(i) for i in df...]生成的列表转成数组后,是个一维的object数组,每个元素是元组,所以shape只有行数(10,),看不到列数。而且这种object类型的数组根本没法发挥Numpy的向量化优势,速度反而快不了多少,完全违背咱们转Numpy的初衷。
最后总结一下
- 要最快的计算速度:用
df.to_numpy()生成纯二维数组,表头单独存变量,这是最优解 - 要表头和数据绑定:用
df.to_records(index=False)生成结构化数组,牺牲一点速度换便捷性
两种方式都能保住数据类型,也满足你查阅表头的需求,完美解决你的问题~
内容的提问来源于stack exchange,提问作者GivenX
相关产品推荐
相关产品推荐

