-
问题背景
- 在使用 NumPy 计算统计结果时发现,NumPy 能够接受原始数据列表来计算标准差,却无法接受经过计算后的结果列表。
- 尝试将
std(f10)
替换为std(solf10)
,但引发了错误:AttributeError: 'Float' object has no attribute 'sqrt'
。 - 使用
print(type(f10), type(solf10))
检查数据结构,发现它们都是<class 'list'>
类型,推测数据结构并非导致问题的根源。
-
解决方案
- 答案 1 指出问题在于
solf10
列表中包含的元素是sympy
的Float
对象,而非 NumPy 可以识别的 C double 对象。因此,需要将这些sympy
对象显式转换为真正的浮点数。 - 答案 2 指出了
m10kg
列表中元素的类型问题。由于整数除法会产生整数结果,导致m10kg
中的元素全部为 1,而不是预期的浮点数。将除法运算符更改为浮点除法x/1000.0
可以解决此问题。
- 答案 1 指出问题在于
代码示例
# 导入必要的库
from sympy import *
from numpy import *
import matplotlib.pyplot as plt
# 常量
g = 9.81
# 给定数据
l1, l2, l3 = 0.023, 0.07492, 0.0325
mw = 0.220
w = g*mw
# 收集的数据
m10 = [1540, 1500, 1400, 1400, 1670]
m10kg = [x / 1000.0 for x in m10] # 将整数除法改为浮点除法
m12 = [1220, 1300, 1200, 1050, 900]
m12kg = [x / 1000.0 for x in m12]
m15 = [770, 790, 740, 760, 750]
m15kg = [x / 1000.0 for x in m15]
# 计算从质量到重力的转换,单位为牛顿
f10, f12, f15 = [x * g for x in m10kg], [y * g for y in m12kg], [z * g for z in m15kg]
# 计算数据的平均值
f10avg, f12avg, f15avg = mean(f10), mean(f12), mean(f15)
# 初始化符号变量
fr, my = symbols('fr, my')
# 关于原点的力矩方程
sumMoments = Eq(fr, (w * l2 + my * (l1 + l2)) / (l1 + l2 + l3))
# 从方程中解出作用在吸管上的牛顿力
solf10 = [solve(sumMoments.subs(my, x)) for x in f10]
solf12 = [solve(sumMoments.subs(my, x)) for x in f12]
solf15 = [solve(sumMoments.subs(my, x)) for x in f15]
# 将列表中的子列表展平
solf10 = [x for sub1 in solf10 for x in sub1]
solf12 = [x for sub1 in solf12 for x in sub1]
solf15 = [x for sub1 in solf15 for x in sub1]
# 计算 `solf10`、`solf12`、`solf15` 的平均值
solf10avg, solf12avg, solf15avg = mean(solf10), mean(solf12), mean(solf15)
# 绘图部分
# ------------------
# X 位置
x = [10, 12, 15]
# 注释样式
# plt.xkcd()
fig = plt.figure()
ax = fig.add_subplot(111)
offset = .5
# 绘制误差线图
ax.errorbar(x, [solf10avg, solf12avg, solf15avg], yerr=[std(f10), std(f12), std(f15)], lw=1.5)
# 添加文本标签
plt.text(x[0], solf10avg + offset, r' $F_{10 cm}=\ %.3f \ N$' % (solf10avg), fontsize=18)
plt.text(x[2], solf15avg + offset, r' $F_{15 cm}=\ %.3f \ N$' % (solf15avg), fontsize=18)
plt.text(x[1], solf12avg + offset, r' $F_{12 cm}=\ %.3f \ N$' % (solf12avg), fontsize=18)
# 设置坐标轴范围
plt.xlim([9, 20])
plt.ylim([0, 20])
# 设置标题、标签和刻度
plt.title("Straw Yield Point Test", fontsize=24)
plt.xlabel("Length (cm)", fontsize=18)
plt.ylabel("Axial Force on Straw\n at Yield (N)", fontsize=18)
plt.minorticks_on()
plt.grid(which="both")
# 保存图像
# plt.savefig('fig_1.pdf')
# 显示图像
plt.show()
通过正确的数据类型转换,上述代码将能够在 solf10
、solf12
、solf15
上计算标准差,并在最后生成所需的图表。