读取文件并在Python中绘制CDF

Pha*_*lav 7 python numpy matplotlib scipy cdf

我需要在几秒钟内读取带有时间戳的长文件,以及使用numpy或scipy的CDF图.我确实试过numpy,但似乎输出不是它应该是什么.以下代码:任何建议表示赞赏.

import numpy as np
import matplotlib.pyplot as plt

data = np.loadtxt('Filename.txt')
sorted_data = np.sort(data)
cumulative = np.cumsum(sorted_data)

plt.plot(cumulative)
plt.show()
Run Code Online (Sandbox Code Playgroud)

tmd*_*son 19

您有两种选择:

1:您可以先将数据打包.这可以通过以下numpy.histogram功能轻松完成:

import numpy as np
import matplotlib.pyplot as plt

data = np.loadtxt('Filename.txt')

# Choose how many bins you want here
num_bins = 20

# Use the histogram function to bin the data
counts, bin_edges = np.histogram(data, bins=num_bins, normed=True)

# Now find the cdf
cdf = np.cumsum(counts)

# And finally plot the cdf
plt.plot(bin_edges[1:], cdf)

plt.show()

2:而不是使用numpy.cumsum,只是将sorted_data数组绘制成小于数组中每个元素的项目数(有关详细信息,参阅此答案/sf/answers/818465581/):

import numpy as np

import matplotlib.pyplot as plt

data = np.loadtxt('Filename.txt')

sorted_data = np.sort(data)

yvals=np.arange(len(sorted_data))/float(len(sorted_data)-1)

plt.plot(sorted_data,yvals)

plt.show()


Ame*_*deo 6

为了完整性,您还应该考虑:

  • 重复:您可能在数据中多次拥有同一点。
  • 点之间的距离可以不同
  • 点数可以浮动

您可以使用来numpy.histogram设置垃圾箱边缘,以使每个垃圾箱仅收集一个点的所有出现。您应该保留density=False,因为根据文档:

请注意,除非选择了单位宽度的bin,否则直方图值的总和将不等于1。

您可以将每个bin中的元素数量标准化除以数据大小。

import numpy as np
import matplotlib.pyplot as plt

def cdf(data):

    data_size=len(data)

    # Set bins edges
    data_set=sorted(set(data))
    bins=np.append(data_set, data_set[-1]+1)

    # Use the histogram function to bin the data
    counts, bin_edges = np.histogram(data, bins=bins, density=False)

    counts=counts.astype(float)/data_size

    # Find the cdf
    cdf = np.cumsum(counts)

    # Plot the cdf
    plt.plot(bin_edges[0:-1], cdf,linestyle='--', marker="o", color='b')
    plt.ylim((0,1))
    plt.ylabel("CDF")
    plt.grid(True)

    plt.show()
Run Code Online (Sandbox Code Playgroud)

例如,具有以下数据:

#[ 0.   0.   0.1  0.1  0.2  0.2  0.3  0.3  0.4  0.4  0.6  0.8  1.   1.2]
data = np.concatenate((np.arange(0,0.5,0.1),np.arange(0.6,1.4,0.2),np.arange(0,0.5,0.1)))
cdf(data)
Run Code Online (Sandbox Code Playgroud)

你会得到:

CDF


您还可以对cdf进行插值以获得连续函数(使用线性插值或三次样条曲线):

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import interp1d

def cdf(data):

    data_size=len(data)

    # Set bins edges
    data_set=sorted(set(data))
    bins=np.append(data_set, data_set[-1]+1)

    # Use the histogram function to bin the data
    counts, bin_edges = np.histogram(data, bins=bins, density=False)

    counts=counts.astype(float)/data_size

    # Find the cdf
    cdf = np.cumsum(counts)

    x = bin_edges[0:-1]
    y = cdf

    f = interp1d(x, y)
    f2 = interp1d(x, y, kind='cubic')

    xnew = np.linspace(0, max(x), num=1000, endpoint=True)

    # Plot the cdf
    plt.plot(x, y, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--')
    plt.legend(['data', 'linear', 'cubic'], loc='best')
    plt.title("Interpolation")
    plt.ylim((0,1))
    plt.ylabel("CDF")
    plt.grid(True)

    plt.show()
Run Code Online (Sandbox Code Playgroud)

插补