3.python的几个函数:itertools.combinations()排列组合、zip()压缩打包、format、enumerate、np.linalg.norm求范数

本文详细介绍了Python中的几个关键函数,包括`itertools.combinations()`用于生成集合和列表的无重复组合,`combinations_with_replacement()`允许元素自我组合,`zip()`进行数据压缩与解压缩,`format()`进行字符串格式化,`enumerate()`生成索引序列,以及`np.linalg.norm()`计算范数。

1.itertools.combinations()

官方文档镇楼:官方文档传送门,点击这里!
官方文档讲解的很详细,还配example。

1.1 对于集合

集合本身具有去重的特性(互异性),还有就是itertools在Py3里面返回的是一个地址!需要转化为list才可以打印出来,具体请看下面栗子:

from itertools import combinations
s={'a','a','a','b','b'}
print(combinations(s,2))  

在这里插入图片描述
结果显示,打印在了后面那个地址里面,解决办法so easy!!!

print(list(combinations(s,2)))

在这里插入图片描述
看到了么,这里输入集合的话,排序时候会自动去重。接下来看列表的效果

1.2 对列表

from itertools import combinations
s=['a','a','a','b','b']
print(list(combinations(s,2)))

在这里插入图片描述
列表的话是打印出来的全部(不包括自己和自己的组合以外)的组合。

因为:
在这里插入图片描述
官方解释,这个不包括重复元素本身。

2. combinations_with_replacement()

官方文档同上面那个链接!
这个区别就是元素可以自己和自己组合。

2.1 集合

from itertools import combinations_with_replacement
s={'a','a','a','b','b'}
print(list(combinations_with_replacement(s,2)))

在这里插入图片描述

2.2 列表

from itertools import combinations_with_replacement
s=['a','a','a','b','b']
print(list(combinations_with_replacement(s,2)))

在这里插入图片描述

3.zip(), *zip()

a=[1,2,3,4]
b=[5,6,7,8,9]
zipped=zip(a,b)

在这里插入图片描述
py3.好多这种啊,输出的是对象,需要转化一下
在这里插入图片描述
在这里插入图片描述
压缩与解压缩。

4. format()

可以代替占位符%的一种写法,字符串格式化,强大!直接上栗子!

# 不设置参数
print("{} {}".format("hello","world"),\
"{2} {0} {1}".format("love","China","I"),sep=".")

在这里插入图片描述

# 设置参数
print("1.我{a},你{b}".format(a="很帅",b="也很帅"),'\n',\
     "2.我{c},你{d}".format(**{"c":"很帅","d":"也很帅"}),'\n',\
     "3.我{0[0]},你{0[1]}".format(['很帅','也很帅']))

在这里插入图片描述
参考菜鸟:菜鸟传送门!点击这里

5.enumerate()

这个函数就是将数据组合成一个索引序列,输出数据和数据下标。

suibian = ["清","北","复","交"]
print(list(enumerate(suibian,start=1))) # 默认start=0

在这里插入图片描述
也可以使用for循环,如下:

suibian = ["清","北","复","交"]
for i ,element in enumerate(suibian,start=1):
    print (i , element)

在这里插入图片描述

6. np.linalg.norm()求范数

np.linalg.norm(x, ord=None, axis=None, keepdims=False)
参数解释取值
默认L2L2范数
ord=1L1绝对值
ord=2L2
ord=np.inf无穷范数max()
axis=0跨行
axis=1跨列

以上。

import numpy as np import matplotlib.pyplot as plt import itertools import random from matplotlib.animation import FuncAnimation # ====== 常量 ====== DIRECTIONS = [ np.array([1.0, 0.0]), np.array([0.5, np.sqrt(3) / 2]), np.array([-0.5, np.sqrt(3) / 2]) ] ROD_LEN = 0.8 BOND_GAP = 0.08 ATOM_CLR = "#2e6bd9" # 自由原子 LOCKED_CLR = "green" # 已成键原子 ENDPOINT_CLR = "orange" # 链条端点 BOND_COLOR = {"A": "red", "B": "yellow"} # 区分 A / B # ====== 三角格点 ====== def tri_lattice_points(L): pts = [] for j in range(L): for i in range(L): x = i + 0.5 * (j % 2) y = j * np.sqrt(3) / 2 pts.append((x, y)) return np.asarray(pts) def lattice_neighbors(L, index): pts = tri_lattice_points(L) c = pts[index] neighbors = [] for j, p in enumerate(pts): if np.isclose(np.linalg.norm(c - p), 1.0, atol=1e-6): neighbors.append(j) return neighbors # ====== 判定函数 ====== def equilateral_side1(c1, c2, c3, tol=1e-3): d12 = np.linalg.norm(c1 - c2) d23 = np.linalg.norm(c2 - c3) d31 = np.linalg.norm(c3 - c1) return (np.isclose(d12, 1.0, atol=tol) and np.isclose(d23, 1.0, atol=tol) and np.isclose(d31, 1.0, atol=tol)) def is_collinear(c1, c2, c3): if np.isclose(c1[1], c2[1]) and np.isclose(c2[1], c3[1]): return True vec1 = c2 - c1 vec2 = c3 - c1 cross = vec1[0] * vec2[1] - vec1[1] * vec2[0] return np.isclose(cross, 0, atol=1e-6) def triangle_type(c1, d1, c2, d2, c3, d3): if is_collinear(c1, c2, c3): return None dirs = {d1, d2, d3} if len(dirs) == 1: return "A" if len(dirs) == 3: edges = [c2 - c1, c3 - c2, c1 - c3] edges = [e / np.linalg.norm(e) for e in edges] centers = [(c1, d1), (c2, d2), (c3, d3)] for center, d in centers: v = DIRECTIONS[d] / np.linalg.norm(DIRECTIONS[d]) if not any(abs(np.dot(v, e)) > 0.99 for e in edges): return None for other, _ in centers: if np.allclose(other, center): continue vec = other - center cross = abs(np.cross(v, vec / np.linalg.norm(vec))) if cross < 1e-6: return None return "B" return None # ====== 原子绘制 ====== def atom_endpoints(center, dir_idx, rod_len=ROD_LEN, inner_gap=BOND_GAP): v = DIRECTIONS[dir_idx] / np.linalg.norm(DIRECTIONS[dir_idx]) half = rod_len / 2.0 - inner_gap return center - half * v, center + half * v def closest_side_connection(centerA, dirA, centerB, dirB): a1, a2 = atom_endpoints(centerA, dirA) b1, b2 = atom_endpoints(centerB, dirB) candidates = [ (np.linalg.norm(a1 - b1), a1, b1), (np.linalg.norm(a1 - b2), a1, b2), (np.linalg.norm(a2 - b1), a2, b1), (np.linalg.norm(a2 - b2), a2, b2), ] _, pa, pb = min(candidates, key=lambda x: x[0]) return pa, pb # ====== 仿真类 ====== class Simulation: def __init__(self, L=6, N=12, seed=42): np.random.seed(seed) self.L = L self.points = tri_lattice_points(L) idxs = np.random.choice(len(self.points), size=N, replace=False) self.atoms = [(idx, np.random.randint(0, 3)) for idx in idxs] self.locked = [False] * N self.used_in_B = [False] * N self.triangles = [] self.has_B = False self.locked_edges = set() self.chain_atoms = set() self.chain_triangles = [] self.chain_endpoints = set() def step(self): new_tris = [] coords = [self.points[idx] for idx, _ in self.atoms] dirs = [d for _, d in self.atoms] for (i, j, k) in itertools.combinations(range(len(self.atoms)), 3): # 只有 B 类原子才会被 used_in_B 标记,因此它们不会参与后续成键 if self.used_in_B[i] or self.used_in_B[j] or self.used_in_B[k]: continue edges = [(min(i, j), max(i, j)), (min(j, k), max(j, k)), (min(k, i), max(k, i))] if any(edge in self.locked_edges for edge in edges): continue c1, c2, c3 = coords[i], coords[j], coords[k] if equilateral_side1(c1, c2, c3): t = triangle_type(c1, dirs[i], c2, dirs[j], c3, dirs[k]) if t == "B" and not self.has_B: new_tris.append((i, j, k, "B")) self.has_B = True for idx in (i, j, k): self.used_in_B[idx] = True self.locked[idx] = True self.locked_edges.update(edges) elif t == "A" and self.has_B: tri_set = {i, j, k} if not self.chain_triangles: # 第一条A链,三原子都没被A链用过即可 if all(idx not in self.chain_atoms for idx in tri_set): new_tris.append((i, j, k, "A")) self.chain_triangles.append((i, j, k)) self.chain_atoms.update(tri_set) self.chain_endpoints = set(tri_set) for idx in (i, j, k): self.locked[idx] = True self.locked_edges.update(edges) else: # 只允许新A型三角形与A链端点和一个新原子组成 endpoints = self.chain_endpoints inter = tri_set & endpoints if len(inter) == 2 and len(tri_set - self.chain_atoms) == 1: new_tris.append((i, j, k, "A")) self.chain_triangles.append((i, j, k)) self.chain_atoms.update(tri_set) new_atom = list(tri_set - self.chain_atoms)[0] covered = list(inter) # 计算链条中心 chain_centers = [self.points[self.atoms[idx][0]] for idx in self.chain_atoms] chain_center = np.mean(chain_centers, axis=0) # 计算两个被覆盖端点到链中心的距离 dists = [np.linalg.norm(self.points[self.atoms[c][0]] - chain_center) for c in covered] # 靠近链中心的端点变为非端点,远离中心的端点保留 min_idx = np.argmin(dists) # 移除靠近中心的端点 self.chain_endpoints.discard(covered[min_idx]) # 新增新原子为端点 self.chain_endpoints.add(new_atom) for idx in (i, j, k): self.locked[idx] = True self.locked_edges.update(edges) # ====== 强制生长A链 ====== # 如果A链已存在且有端点,强制将一个自由原子移动到端点附近并尝试生成A型三角形 if self.chain_endpoints and len(self.chain_atoms) < len(self.atoms): # 找到所有未锁定的自由原子 free_idxs = [idx for idx, locked in enumerate(self.locked) if not locked and idx not in self.chain_atoms] if free_idxs and self.chain_endpoints: # 任选一个端点和一个自由原子 endpoint = next(iter(self.chain_endpoints)) free_idx = free_idxs[0] # 让自由原子移动到端点最近的邻居格点,并方向与端点原子一致 endpoint_site, endpoint_dir = self.atoms[endpoint] endpoint_pos = self.points[endpoint_site] neigh = lattice_neighbors(self.L, endpoint_site) # 只选未被占用的邻居 occupied_sites = {self.atoms[idx][0] for idx, locked in enumerate(self.locked) if locked} occupied_sites |= {self.atoms[idx][0] for idx in self.chain_atoms} free_neigh = [n for n in neigh if n not in occupied_sites] if free_neigh: new_site = free_neigh[0] self.atoms[free_idx] = (new_site, endpoint_dir) # 立即尝试生成新的A型三角形(下次step会自动检测) self.triangles.extend(new_tris) occupied_sites = {self.atoms[idx][0] for idx, locked in enumerate(self.locked) if locked} for idx, locked in enumerate(self.locked): if not locked: site, d = self.atoms[idx] neigh = lattice_neighbors(self.L, site) free_neigh = [n for n in neigh if n not in occupied_sites] if free_neigh: site = random.choice(free_neigh) d = random.randint(0, 2) self.atoms[idx] = (site, d) occupied_sites.add(site) return all(self.locked) # ====== 绘制函数 ====== def plot_frame(sim, ax): ax.clear() coords = [sim.points[idx] for idx, _ in sim.atoms] dirs = [d for _, d in sim.atoms] atom_counts = {a: 0 for a in sim.chain_atoms} for tri in sim.chain_triangles: for v in tri: atom_counts[v] += 1 endpoints = {a for a, c in atom_counts.items() if c == 1} for (center, dir_idx), locked, idx in zip(zip(coords, dirs), sim.locked, range(len(sim.atoms))): p1, p2 = atom_endpoints(center, dir_idx) if idx in endpoints: color = ENDPOINT_CLR else: color = LOCKED_CLR if locked else ATOM_CLR ax.plot([p1[0], p2[0]], [p1[1], p2[1]], color=color, lw=6, solid_capstyle="round") for (i, j, k, t) in sim.triangles: edges = [(i, j), (j, k), (k, i)] for a, b in edges: pa, pb = closest_side_connection(coords[a], dirs[a], coords[b], dirs[b]) ax.plot([pa[0], pb[0]], [pa[1], pb[1]], color=BOND_COLOR[t], lw=2) # 固定画幅为 9×9 ax.set_xlim(-0.5, 8.5) ax.set_ylim(-0.5, 8.5) ax.set_aspect("equal") # ====== 动画 ====== def run_animation(): sim = Simulation(L=6, N=12, seed=1) fig, ax = plt.subplots(figsize=(6, 6)) def update(frame): done = sim.step() plot_frame(sim, ax) if done: ani.event_source.stop() ani = FuncAnimation(fig, update, frames=500, interval=200) plt.show() # ====== 运行动画 ====== run_animation()我现在遇到了问题,A型键无法生长
最新发布
09-09
新构建锥形编队几何关系,使其能够适用于题目要 import numpy as np import matplotlib.pyplot as plt from scipy.optimize import least_squares import pandas as pd import os def generate_cone_formation(n=5, spacing=50, angle=0): """ 生成锥形编队无人机位置 参数: n - 无人机数量 spacing - 间距 angle - 编队方向(弧度) 返回: positions - 无人机位置列表 """ positions = [] for i in range(n): x = i * spacing * np.cos(angle) y = i * spacing * np.sin(angle) positions.append(np.array([x, y])) return positions def visualize_cone_formation(positions, save_path=None): """ 可视化锥形编队 参数: positions - 无人机位置列表 save_path - 保存路径 """ fig, ax = plt.subplots(figsize=(10, 6)) # 绘制无人机位置 for i, pos in enumerate(positions): ax.scatter(pos[0], pos[1], color=&#39;blue&#39;, s=100, edgecolor=&#39;black&#39;) ax.text(pos[0] + 2, pos[1] + 2, f"UAV{i}", fontsize=10) # 绘制编队方向线 x_vals = [pos[0] for pos in positions] y_vals = [pos[1] for pos in positions] ax.plot(x_vals, y_vals, &#39;r--&#39;, label=&#39;编队轴线&#39;) # 设置图形属性 ax.set_title("锥形编队示意图", fontsize=14) ax.set_xlabel("X 坐标 (m)") ax.set_ylabel("Y 坐标 (m)") ax.axhline(0, color=&#39;gray&#39;, linestyle=&#39;--&#39;, linewidth=0.5) ax.axvline(0, color=&#39;gray&#39;, linestyle=&#39;--&#39;, linewidth=0.5) ax.legend() ax.grid(True) ax.axis(&#39;equal&#39;) if save_path: plt.savefig(save_path, dpi=300, bbox_inches=&#39;tight&#39;) plt.close() def cone_resection_position(beacons, angles): def residuals(p): x, y = p residuals = [] from itertools import combinations beacon_pairs = list(combinations(range(len(beacons)), 2)) for i, j in beacon_pairs: vec_i = beacons[i] - [x, y] vec_j = beacons[j] - [x, y] norm_i = np.linalg.norm(vec_i) norm_j = np.linalg.norm(vec_j) if norm_i == 0 or norm_j == 0: residuals.append(0.0) continue dot = np.dot(vec_i, vec_j) cos_angle = np.clip(dot / (norm_i * norm_j), -1.0, 1.0) calc_angle = np.arccos(cos_angle) residuals.append(calc_angle - angles[(i, j)]) if len(beacons) >= 2: dir_vec = beacons[1] - beacons[0] dir_vec = dir_vec / np.linalg.norm(dir_vec) point_to_beacon0 = [x, y] - beacons[0] distance = np.linalg.norm(point_to_beacon0 - np.dot(point_to_beacon0, dir_vec) * dir_vec) residuals.append(distance) return residuals beacon_center = np.mean(beacons, axis=0) x0 = [beacon_center[0], beacon_center[1]] result = least_squares(residuals, x0, loss=&#39;soft_l1&#39;, ftol=1e-8, xtol=1e-8) return result.x if result.success else x0 def adjust_cone_formation(initial_positions, max_iterations=100, tolerance=1e-6): """ 调整锥形编队 参数: initial_positions - 初始位置 max_iterations - 最大迭代次数 tolerance - 收敛阈值 返回: 调整后的位置和调整过程 """ positions = np.array(initial_positions) adjustment_process = [positions.copy()] for iteration in range(max_iterations): # 计算编队轴线 if len(positions) > 1: # 使用主成分分析确定主要方向 centered = positions - np.mean(positions, axis=0) cov_matrix = np.cov(centered, rowvar=False) eigen_values, eigen_vectors = np.linalg.eig(cov_matrix) main_dir = eigen_vectors[:, np.argmax(eigen_values)] # 确保方向向量是单位向量 main_dir = main_dir / np.linalg.norm(main_dir) else: main_dir = np.array([1, 0]) # 默认方向 # 计算每个点在主方向上的投影 projections = [] for pos in positions: proj = np.dot(pos - positions[0], main_dir) projections.append(proj) # 理想间距 if len(positions) > 1: ideal_spacing = np.mean([np.linalg.norm(positions[i+1] - positions[i]) for i in range(len(positions)-1)]) else: ideal_spacing = 50 # 默认间距 # 创建理想位置 ideal_positions = [positions[0] + i * ideal_spacing * main_dir for i in range(len(positions))] # 计算误差并更新位置 error = 0 new_positions = [] for i, pos in enumerate(positions): ideal_pos = ideal_positions[i] direction = ideal_pos - pos new_pos = pos + 0.5 * direction # 使用0.5作为学习率 new_positions.append(new_pos) error += np.linalg.norm(pos - ideal_pos) positions = np.array(new_positions) adjustment_process.append(positions.copy()) # 检查收敛 if error < tolerance: print(f"Converged after {iteration} iterations") break return { &#39;final_positions&#39;: positions, &#39;adjustment_process&#39;: adjustment_process, &#39;ideal_spacing&#39;: ideal_spacing, &#39;main_direction&#39;: main_dir } if __name__ == "__main__": SAVE_DIR = "output/images" os.makedirs(SAVE_DIR, exist_ok=True) # 生成测试数据 true_positions = generate_cone_formation(n=5, spacing=50, angle=np.radians(30)) noisy_positions = [pos + np.random.normal(0, 5, 2) for pos in true_positions] visualize_cone_formation(noisy_positions, f"{SAVE_DIR}/noisy_cone_formation.png") beacon_indices = [0, 4] beacons = [noisy_positions[i] for i in beacon_indices] receiver_index = 2 receiver_pos = noisy_positions[receiver_index] # 计算所有发射机对的角度 from itertools import combinations angles = {} for i, j in combinations(range(len(beacons)), 2): vec_i = beacons[i] - receiver_pos vec_j = beacons[j] - receiver_pos dot = np.dot(vec_i, vec_j) norm_i = np.linalg.norm(vec_i) norm_j = np.linalg.norm(vec_j) cos_angle = dot / (norm_i * norm_j) if norm_i > 0 and norm_j > 0 else 0 angles[(i, j)] = np.arccos(np.clip(cos_angle, -1, 1)) estimated_pos = cone_resection_position(beacons, angles) print(f"真实位置: {true_positions[receiver_index]}") print(f"测量位置: {receiver_pos}") print(f"估计位置: {estimated_pos}") print(f"误差: {np.linalg.norm(true_positions[receiver_index] - estimated_pos):.2f}m") # 可视化定位结果 fig, ax = plt.subplots(figsize=(10, 6)) for i, pos in enumerate(true_positions): ax.scatter(pos[0], pos[1], color=&#39;blue&#39;, label=&#39;真实位置&#39; if i == 0 else "", s=100) ax.text(pos[0]+2, pos[1]+2, f"UAV{i}", fontsize=10) for i, pos in enumerate(noisy_positions): ax.scatter(pos[0], pos[1], color=&#39;red&#39;, label=&#39;测量位置&#39; if i == 0 else "", s=80, marker=&#39;x&#39;) ax.scatter(estimated_pos[0], estimated_pos[1], color=&#39;green&#39;, label=&#39;估计位置&#39;, s=120, marker=&#39;^&#39;) for beacon in beacons: ax.plot([estimated_pos[0], beacon[0]], [estimated_pos[1], beacon[1]], &#39;g--&#39;) ax.set_title("锥形编队定位示例", fontsize=14) ax.legend() ax.grid(True) ax.axis(&#39;equal&#39;) plt.savefig(f"{SAVE_DIR}/cone_positioning_example.png", dpi=300, bbox_inches=&#39;tight&#39;) plt.close()
08-22
import numpy as np def compute_between_class_scatter(X, y): """ Compute the between-class scatter matrix. Parameters: X : array-like of shape (n_samples, n_features) Feature data. y : array-like of shape (n_samples,) Target labels corresponding to each sample. Returns: Sb : ndarray of shape (n_features, n_features) Between-class scatter matrix. """ unique_classes = np.unique(y) overall_mean = np.mean(X, axis=0).reshape(-1, 1) Sb = np.zeros((X.shape[1], X.shape[1])) for c in unique_classes: Xi = X[y == c] class_mean = np.mean(Xi, axis=0).reshape(-1, 1) ni = Xi.shape[0] Sb += ni * (class_mean - overall_mean).dot((class_mean - overall_mean).T) return Sb def compute_within_class_scatter(X, y): """ Compute the within-class scatter matrix. Parameters: X : array-like of shape (n_samples, n_features) Feature data. y : array-like of shape (n_samples,) Target labels corresponding to each sample. Returns: Sw : ndarray of shape (n_features, n_features) Within-class scatter matrix. """ unique_classes = np.unique(y) Sw = np.zeros((X.shape[1], X.shape[1])) for c in unique_classes: Xi = X[y == c] class_mean = np.mean(Xi, axis=0).reshape(-1, 1) Si = np.sum( [(x.reshape(-1, 1) - class_mean).dot((x.reshape(-1, 1) - class_mean).T) for x in Xi], axis=0 ) Sw += Si return Sw def compute_discriminability_criterion(Sw, Sb): """ Compute the discriminability criterion function value J. Parameters: Sw : ndarray of shape (n_features, n_features) Within-class scatter matrix. Sb : ndarray of shape (n_features, n_features) Between-class scatter matrix. Returns: J_value : float Discriminability criterion function value. """ eigenvalues, _ = np.linalg.eig(np.linalg.inv(Sw).dot(Sb)) J_value = np.sum(eigenvalues) return J_value # Example Usage if __name__ == "__main__": # Generate synthetic dataset with two classes from sklearn.datasets import make_classification X, y = make_classification(n_samples=100, n_features=2, n_informative=2, n_redundant=0, n_clusters_per_class=1, random_state=42) # Compute matrices Sb = compute_between_class_scatter(X, y) Sw = compute_within_class_scatter(X, y) # Compute J value J_value = compute_discriminability_criterion(Sw, Sb) print(f"Discriminability Criterion Function Value J: {J_value}") 用上述代码实现下面问题:对Iris数据进行两个特征选择,共6种组合,计算类别可分性准则函数J值,得出最好的分类组合,画出六种组合的分布图。使用最小距离法(均值点)或k近邻法(k取1、3、5)(可以直接调用方法)、对6种组合分别使用不同方法进行基于120个训练样本30个测试样本的学习误差和测试计算
05-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值