如何使用具有大量行的 DataFrame 使线图可读
Posted
技术标签:
【中文标题】如何使用具有大量行的 DataFrame 使线图可读【英文标题】:How to make readable a line plot using a DataFrame with a large number of rows 【发布时间】:2019-08-04 17:48:08 【问题描述】:我有一个 1,000,000 x 2 的 DataFrame 对象,其中包含我试图从视觉上理解的数据。它基本上模拟了 1,000,000 个事件,其中沿网络传输的数据包根据缓冲区的大小排队或丢弃。因此,两列值是 Packets in Queue 和 Packets Dropped。
我正在尝试使用 Python、Matplotlib 和 Jupyter Notebooks 制作折线图,其中 x 轴上的事件 ID 和 y 轴上特定 ID 点处队列中的数据包数。应该有两行,第一行表示队列中的数据包数,第二行表示丢弃的数据包数。但是,鉴于有超过 1,000,000 次模拟,该图难以理解。这些价值观太挤在一起了。是否可以制作一个包含 1,000,000 个事件实例的可读图表,还是我需要大幅减少事件的数量?
【问题讨论】:
【参考方案1】:拥有一百万个数据点需要大量的努力并放大才能看到它们的细节。 Plotly 有一些很好的工具可以放大和缩小绘图以及沿 x 轴滑动数据窗口。
如果你对一些平均数没问题,你可以绘制一个移动平均线并接近十万点。您可以将两个子图相互堆叠,以合理详细地查看两列数据。您当然可以对它们进行更多平均,但您会失去查看细节的能力。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def moving_avg(x, N=30):
return np.convolve(x, np.ones((N,))/N, mode='valid')
plt.figure(figsize = (16,12))
plt.subplot(3,1,1)
x = np.random.random(1000)
plt.plot(x, linewidth = 1, alpha = 0.5, label = 'linewidth = 1')
plt.plot(moving_avg(x, 10), 'C0', label = 'moving average, N = 10')
plt.xlim(0,len(x))
plt.legend(loc=2)
plt.subplot(3,1,2)
x = np.random.random(10000)
plt.plot(x, linewidth = 0.2, alpha = 0.5, label = 'linewidth = 0.2')
plt.plot(moving_avg(x, 100), 'C0', label = 'moving average, N = 100')
plt.xlim(0,len(x))
plt.legend(loc=2)
plt.subplot(3,1,3)
x = np.random.random(100000)
plt.plot(x, linewidth = 0.05, alpha = 0.5, label = 'linewidth = 0.05')
plt.plot(moving_avg(x, 500), 'C0', label = 'moving average, N = 500')
plt.xlim(0,len(x))
plt.legend(loc=2)
plt.tight_layout()
【讨论】:
【参考方案2】:试试直方图
from matplotlib.pyplot import hist
import pandas as pd
df = pd.DataFrame()
df['x'] = np.random.rand(1000000)
hist(df.index, weights=df.x, bins=1000)
plt.show()
方法 2 线图
df['x'] = np.random.rand(1000000)
df['y'] = np.random.rand(1000000)
w = 1000
v1 = df['x'].rolling(min_periods=1, window=w).sum()[[i*w for i in range(1, int(len(df)/w))]]/w
v2 = df['y'].rolling(min_periods=1, window=w).sum()[[i*w for i in range(1, int(len(df)/w))]]/w
plt.plot(np.arange(len(v1)),v1, c='b')
plt.plot(np.arange(len(v1)),v2, c='r')
plt.show()
我们正在计算 w=1000 点的平均值,即平均 w 值并绘制它们。
每 1000 个间隔扣 1000000 个点时如下所示
【讨论】:
对不起,我应该说它需要是一个有两条线的线图,第一条是队列中的数据包数,第二条是丢弃的数据包数。以上是关于如何使用具有大量行的 DataFrame 使线图可读的主要内容,如果未能解决你的问题,请参考以下文章
为啥在具有 1 行的 DataFrame 上的 collect() 使用 2000 个执行器?