web-dev-qa-db-ja.com

ファイルを読み取り、CDFをPython

タイムスタンプが秒単位の長いファイルを読み取り、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()
6
Phani.lav

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()
 
16
tmdavison

完全を期すために、次のことも考慮する必要があります。

  • 重複:データ内に同じポイントが複数回存在する可能性があります。
  • ポイント間で距離が異なる場合があります
  • ポイントはフロートできます

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)

あなたが得るだろう:

CDF


連続関数を取得するために累積分布関数を補間することもできます(線形補間または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()

Interpolation

4
Amedeo

以下は私の実装のステップです:

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')

図: グラフのリンク

2
vergil_chiou

簡単な答えとして、

plt.plot(sorted_data, np.linspace(0,1,sorted_data.size)

あなたが望むものを手に入れるべきだった

2
nayyarv

これは、繰り返される値が多数ある場合に少し効率的な実装です(一意の値を並べ替えるだけでよいため)。そして、厳密に言えば、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)
1
Allen Downey