基于树莓派与Node-RED的智能家居节能系统:从物联网原理到实践
2026/6/3 14:56:16
# 示例:Pandas Series 转 NumPy 时的维度变化 import pandas as pd import numpy as np s = pd.Series([1, 2, 3, 4]) arr = s.values # 此时 arr 为一维 (4,) print(arr.shape) # 输出: (4,) # 若需保持二维结构,应显式重塑 arr_2d = s.values.reshape(-1, 1) print(arr_2d.shape) # 输出: (4, 1).values时警惕自动降维行为reshape(-1, 1)以保持二维结构| 数据类型 | 原始维度 | 转 NumPy 后维度 |
|---|---|---|
| Pandas Series (n,) | (n,) | (n,) |
| Pandas DataFrame (n, 1) | (n, 1) | (n, 1) |
| 单列 Series 转数组 | (n,) | (n,) — 易引发错误 |
import numpy as np arr = np.arange(6) reshaped = arr.reshape(2, 3) print(reshaped)该代码将一维数组[0,1,2,3,4,5]转换为2×3矩阵。原始数据按行填充,体现C顺序存储规则。| 原始形状 | 目标形状 | 是否合法 |
|---|---|---|
| (6,) | (2, 3) | 是 |
| (4,) | (3, 2) | 否 |
import numpy as np arr = np.arange(12) # 形状为 (12,) reshaped = arr.reshape(3, 4) # 成功:3×4=12 # invalid = arr.reshape(3, 5) # 抛出 ValueError上述代码中,reshape(3, 4)满足元素总数守恒原则。参数必须为正整数,且乘积等于原数组大小。import numpy as np data = np.arange(6) # [0, 1, 2, 3, 4, 5] matrix = data.reshape((2, 3)) print(matrix)该代码将长度为6的一维数组按行优先顺序重排为2×3矩阵。`reshape` 方法要求元素总数匹配,且默认使用 C 风格顺序(行主序)。ValueError或逻辑错误。-1被用作列表索引,意外访问最后一个元素-1,导致统计偏差data = [10, 20, -1, 40] indices = [data.index(x) for x in data if x > 0] # 错误:未排除-1上述代码看似安全,但若逻辑依赖索引唯一性,-1的存在可能导致重复索引或意外匹配。正确做法是预先清洗数据:clean_data = [x for x in data if x != -1]通过显式过滤占位符,避免隐式语义冲突,提升代码健壮性。import numpy as np x = np.random.rand(4, 3) y = x.T # 转置后内存不连续 z = y.reshape(-1) # 触发隐式拷贝上述代码中,y.flags['C_CONTIGUOUS']为 False,因此reshape返回的是新内存块的副本而非视图。| 数组状态 | 是否共享内存 | 时间开销 |
|---|---|---|
| 连续 | 是(视图) | O(1) |
| 非连续 | 否(副本) | O(n) |
import numpy as np arr = np.array([1, 2, 3, 4], dtype=np.int32) view_as_float = arr.view(dtype=np.float32).reshape(2, 2) print(view_as_float)上述代码将整型数组按`float32`重新解释并重塑为2×2矩阵。由于`int32`和`float32`占用相同字节(4字节),但解释方式不同,输出结果为无意义浮点数。view()更改dtypearr.dtype与预期一致astype()进行安全类型转换| 顺序 | 填充方向 | 适用场景 |
|---|---|---|
| C-order | 行优先 | 默认,C/C++兼容 |
| F-order | 列优先 | Fortran兼容,列操作频繁时更高效 |
import numpy as np arr = np.arange(6) reshaped_c = arr.reshape((2, 3), order='C') reshaped_f = arr.reshape((2, 3), order='F') print("C-order:\n", reshaped_c) print("F-order:\n", reshaped_f)上述代码中,order='C'按0,1,2,3,4,5顺序逐行填充;而order='F'则先填满第一列(0,3),再填第二列(1,4),体现列优先逻辑。这种行为差异直接影响数据局部性与性能表现。采用行优先顺序填充,即最后一个轴变化最快:
import numpy as np arr = np.arange(6).reshape(2, 3, order='C') print(arr) # 输出: # [[0 1 2] # [3 4 5]]元素按内存连续方式依次填入行,符合C语言默认布局。
使用Fortran风格,首个轴变化最慢:
arr_f = np.arange(6).reshape(2, 3, order='F') print(arr_f) # 输出: # [[0 2 4] # [1 3 5]]数据按列填充,适用于特定科学计算场景。
| order参数 | 访问顺序 | 适用场景 |
|---|---|---|
| 'C' | 行优先 | 通用计算、图像处理 |
| 'F' | 列优先 | 线性代数、Fortran接口 |
to_numpy()方法时,开发者常忽略其默认参数copy=False和dtype=None。这可能导致返回数组与原始数据共享内存,修改数组会意外影响源数据。import pandas as pd df = pd.DataFrame({'A': [1, 2, 3]}) arr = df['A'].to_numpy() arr[0] = 99 print(df) # 输出显示 df 被修改!上述代码中,copy=False导致arr与df['A']共享底层数据。若需独立副本,应显式指定copy=True。copy参数以避免副作用dtype显式声明类型,防止隐式转换错误arr = np.array([[1, 2], [3, 4]]) sliced = arr[:, 0] # 视图,可能非连续 contiguous = sliced.copy() # 创建连续副本copy()方法强制生成一个在内存中连续的新数组,确保后续操作不会因内存碎片化而失败。float_arr = contiguous.astype(np.float32)astype()不仅转换数据类型,还会返回一个新的、连续存储的数组。这对于需要固定类型和内存对齐的底层库(如CUDA)至关重要。[[i1, j1], [i2, j2]]转换后可能仅保留值序列,而无法还原原始结构。import numpy as np multi_index = [[0, 1], [2, 3], [4, 5]] flattened = np.array(multi_index).flatten() # 输出: [0 1 2 3 4 5],原始二维结构消失上述代码将二维索引展平为一维数组,丢失了每对索引的逻辑分组关系。解决该问题需显式保存形状信息。import pandas as pd import numpy as np # 示例数据 df = pd.DataFrame({ 'feature_a': [1.0, 2.5, np.nan], 'feature_b': [3.1, 4.2, 5.3] }) # 清洗并转换 df_clean = df.fillna(0).astype(np.float32)使用fillna(0)填补缺失值,避免后续计算中断;astype(np.float32)统一数值类型,减少内存占用并提升后续运算效率。
arr = df_clean.values reshaped = arr.reshape((1, -1)) # 转为单样本多特征格式通过.values提取底层数组,reshape((1, -1))将其转为二维结构,适配机器学习模型输入要求。
Q1 = df['price'].quantile(0.25) Q3 = df['price'].quantile(0.75) IQR = Q3 - Q1 lower_bound = Q1 - 1.5 * IQR upper_bound = Q3 + 1.5 * IQR outliers = df[(df['price'] < lower_bound) | (df['price'] > upper_bound)]但需注意:在医疗数据中,极端血压值可能是危重病例的真实记录,不应简单剔除。| 阶段 | 操作 | 可逆性 |
|---|---|---|
| 原始层 | 保留原始副本 | 是 |
| 清洗层 | 去重、格式标准化 | 部分 |
| 特征层 | 编码、归一化 | 否 |