免责声明:我对 Pandas 很陌生。
我正在进行数值模拟,并希望使用 Pandas 进行最终数据评估。为简单起见,我们假设以下设置:
我的模拟需要一些输入参数(例如 max 和 size)。然后,模拟会产生许多作为时间函数的可观察值(例如 f1(t)、f2(t))。最后,三种不同模拟的结果可能如下所示:
t1 = np.linspace(0, 2, 15)
t2 = np.linspace(0, 2, 21)
t3 = np.linspace(0, 1.5, 16)
df1 = pd.DataFrame({'max': t1.max(), 'size': t1.size, 't': t1, 'f1': t1**2+0, 'f2': t1**3+0})
df2 = pd.DataFrame({'max': t2.max(), 'size': t2.size, 't': t2, 'f1': t2**2+1, 'f2': t2**3+1})
df3 = pd.DataFrame({'max': t3.max(), 'size': t3.size, 't': t3, 'f1': t3**2+2, 'f2': t3**3+2})
其中max和size是每次模拟的参数,t是时间轴,f1 和 f2 是可观察值。
比如说,作为第一个任务,我想为每组参数绘制 f1 的值作为 t 的函数。花了一些时间阅读文档后,我发现 pivot_table 函数可以以正确的方式重新排列我的数据。
df = pd.concat([df1, df2, df3])
df_ms = pd.pivot_table(df, index=['t'], values=['f1', 'f2'], columns=['max', 'size'])
中间问题:这是最好的方法吗?我知道 DataFrame 在其构造函数中有一个 index 参数。将 t 定义为此时的索引会更好吗? (我无法让它与 pivot_table 一起工作)
现在我们可以使用 plot 方法绘制结果数据。
df_ms['f1'].plot()
然而,结果出乎意料。我知道缺少一些数据,因为在对齐不同的 t 轴时,pandas 被迫引入 NaN。
我的问题: 为什么绿色曲线根本不显示?为什么蓝色和红色补丁对齐?是否有一种简单的方法可以跳过图中的 NaN,就像在 matplotlib 中调用 plt.plot(t, f1) 一样?
我知道可以通过插值来填充 NaN。对于给定的情况,二阶样条曲线非常理想。
df_ms['f1'].interpolate(method='spline', order=2).plot()
但是,我想知道为什么这对于简单地绘制数据是必要的。 Matplotlib 的内部线性插值就足够了......
请您参考如下方法:
nan 的行为符合逻辑,但并不总是很直观。
如果绘制一条连续的线,nan 会自然地从 nan 点的两侧删除线段。所以,如果你的数据(绿线)从来没有两个数字作为相邻元素,它就不会被绘制。例如,如果 f1 是 [nan, 1, nan, 1.2, nan, nan, 2.3],则无法绘制线段。
修复 #1:画点而不是线 (plot(t, f1, 'o')),那么您至少会看到所有数据。
修复 #2:在绘图之前从数据中删除所有 nan。让我们假设 t 具有所有值,但 f1 缺少值:
import numpy as np
import matplotlib.pyplot as plt
nonnans = -np.isnan(f1)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(t[nonnans], f1[nonnans])
因此,只需创建一个数组来告诉哪些样本是好的,并仅在绘图中使用这些样本。 (如果您想知道,ax.plot 等同于 plt.plot 但使用推荐的面向对象接口(interface)。)
plot 处理 nan 的方式一开始可能会觉得有点烦人,但一旦掌握它就会非常有用。
