免责声明:我对熊猫很新。
我正在进行数值模拟,并希望将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
轴时,大熊猫被迫引入NaN。
我的问题:
为什么绿色曲线根本不显示?为什么蓝色和红色斑块对齐?有没有一种简单的方法可以跳过绘图中的NaN,只需在matplotlib中调用plt.plot(t, f1)
即可获得的内容?
我知道可以通过插值填充NaN。对于给定的情况,二阶样条是非常理想的。
df_ms['f1'].interpolate(method='spline', order=2).plot()
但是,我想知道为什么这对于简单地绘制数据是必要的。 Matplotlib的内部线性插值就足够了......
答案 0 :(得分:1)
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
,但使用推荐的面向对象的接口。)
plot
对待nan
的方式一开始可能会让人感到有些烦恼,但一旦掌握它就非常有用。
答案 1 :(得分:1)
(2.0,21)
列中的验证值很少,因为该列中没有2个连续的验证值。定义一条线需要两点,因此我们没有看到为该列绘制的任何线条,我们在绘制df.fillna(0)
时可以很容易地看到:
df_ms['f1'].plot()
plt.figure()
df_ms['f1'].fillna(0).plot()
从上述两个图的比较可以看出,其他列也是如此。