タイムスタンプが秒単位の長いファイルを読み取り、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()
2つのオプションがあります。
1:最初にデータをビンに入れることができます。これは、numpy.histogram
関数を使用して簡単に実行できます。
import numpy as np import matplotlib.pyplot as plt data = np.loadtxt( 'Filename.txt') #ここで必要なビンの数を選択します num_bins = 20 #ヒストグラム関数を使用してデータをビンに入れます counts、bin_edges = np.histogram( data、bins = num_bins、normed = True) #ここで、cdf cdf = np.cumsum(counts) #を見つけます。最後に、cdf plt.plot(bin_edges [1:]、cdf) plt.show() をプロットします。
2:numpy.cumsum
を使用するのではなく、配列内の各要素よりも小さいアイテムの数に対してsorted_data
配列をプロットするだけです(詳細については、この回答を参照してください https://stackoverflow.com/a/11692365/588071 ):
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()
完全を期すために、次のことも考慮する必要があります。
numpy.histogram
を使用して、各ビンが1つのポイントのみのすべてのオカレンスを収集するようにビンのエッジを設定できます。ドキュメントによると、次の理由から、density=False
を保持する必要があります。
幅が1のビンを選択しない限り、ヒストグラム値の合計は1に等しくないことに注意してください。
代わりに、各ビンの要素数をデータのサイズで割って正規化できます。
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()
例として、次のデータを使用します。
#[ 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)
あなたが得るだろう:
連続関数を取得するために累積分布関数を補間することもできます(線形補間または3次スプラインのいずれかを使用)。
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()
以下は私の実装のステップです:
1.データを並べ替える
2.すべての「x」の累積確率を計算します
import numpy as np
import matplotlib.pyplab as plt
def cdf(data):
n = len(data)
x = np.sort(data) # sort your data
y = np.arange(1, n + 1) / n # calculate cumulative probability
return x, y
x_data, y_data = cdf(your_data)
plt.plot(x_data, y_data)
例:
test_data = np.random.normal(size= 100)
x_data, y_data = ecdf(test_data)
plt.plot(x_data, y_data, marker= '.', linestyle= 'none')
図: グラフのリンク
簡単な答えとして、
plt.plot(sorted_data, np.linspace(0,1,sorted_data.size)
あなたが望むものを手に入れるべきだった
これは、繰り返される値が多数ある場合に少し効率的な実装です(一意の値を並べ替えるだけでよいため)。そして、厳密に言えば、CDFをステップ関数としてプロットします。
import sys
import numpy as np
import matplotlib.pyplot as plt
from collections import Counter
def read_data(fp):
t = []
for line in fp:
x = float(line.rstrip())
t.append(x)
return t
def main(script, filename=None):
if filename is None:
fp = sys.stdin
else:
fp = open(filename)
t = read_data(fp)
counter = Counter(t)
xs = counter.keys()
xs.sort()
ys = np.cumsum(counter.values()).astype(float)
ys /= ys[-1]
options = dict(linewidth=3, alpha=0.5)
plt.step(xs, ys, where='post', **options)
plt.xlabel('Values')
plt.ylabel('CDF')
plt.show()
if __== '__main__':
main(*sys.argv)