it-swarm.com.de

Lesen Sie die Datei und zeichnen Sie CDF in Python

Ich muss lange Dateien mit Zeitstempel in Sekunden lesen und CDF mit Numpy oder Scipy plotten. Ich habe es mit Numpy versucht, aber die Ausgabe ist NICHT das, was sie sein soll. Der Code unten: Alle Vorschläge geschätzt. 

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

Sie haben zwei Möglichkeiten:

1: Sie können die Daten zuerst einlagern. Dies kann leicht mit der numpy.histogram-Funktion durchgeführt werden:

 import numpy als np 
 import matplotlib.pyplot als plt 
 
 data = np.loadtxt ('Dateiname.txt') 
 [.____. .] # Wählen Sie hier aus, wie viele Fächer Sie möchten. 
 Num_bins = 20 
 
 # Verwenden Sie die Histogrammfunktion, um die Daten 
 In bin zu sortieren, bin_edges = np.histogram ( data, bins = num_bins, normed = true) 
 
 # Nun finden Sie die cdf 
 cdf = np.cumsum (Anzahl) 
 
 # und Plotten Sie schließlich das cdf 
 plt.plot (bin_edges [1:], cdf) 
 
 plt.show () 
 

2: Statt numpy.cumsum verwenden, plotten Sie einfach das sorted_data-Array anhand der Anzahl der Elemente, die kleiner als jedes Element im Array sind (weitere Informationen finden Sie in dieser Antwort https://stackoverflow.com/a/11692365/588071 ):

 import numpy als np 
 
 import matplotlib.pyplot als plt 
 
 data = np.loadtxt ('Dateiname.txt') 
 
 sortierte_Daten = np.sort (Daten) 
 
 yvals = np.arange (len (sortierte_Daten))/float (len (sortierte_Daten) -1) 
 
 plt.plot (sortierte_Daten, yvals) 
 
 plt.show () 
 
16
tmdavison

Der Vollständigkeit halber sollten Sie auch Folgendes berücksichtigen:

  • duplikate: Sie könnten denselben Punkt mehr als einmal in Ihren Daten haben. 
  • punkte können unterschiedliche Abstände untereinander haben
  • punkte können Float sein

Sie können numpy.histogram verwenden, um die Kanten der Ablagen so festzulegen, dass in jeder Ablage alle Vorkommen nur eines Punkts erfasst werden. Sie sollten density=False behalten, weil laut Dokumentation:

Beachten Sie, dass die Summe der Histogrammwerte nicht gleich 1 ist, es sei denn, es werden Klassen mit der Breite von 1 ausgewählt

Sie können stattdessen die Anzahl der Elemente in jeder Ablage normalisieren, indem Sie sie durch die Größe Ihrer Daten teilen. 

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

Als Beispiel mit folgenden Daten:

#[ 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)

sie würden bekommen:

 CDF


Sie können das Dokument auch interpolieren, um eine stetige Funktion zu erhalten (entweder mit einer linearen Interpolation oder einem kubischen Spline):

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

Das Folgende ist der Schritt meiner Implementierung:

1.sortieren Sie Ihre Daten

2.berechnen Sie die kumulative Wahrscheinlichkeit jedes '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) 

Beispiel:

test_data = np.random.normal(size= 100)
x_data, y_data = ecdf(test_data)
plt.plot(x_data, y_data, marker= '.', linestyle= 'none')

Abbildung: Der Link zur Grafik

2
vergil_chiou

Als schnelle Antwort

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

hätte dich bekommen, was du wolltest

2
nayyarv

Eine Implementierung ist etwas effizienter, wenn es viele wiederholte Werte gibt (da nur die eindeutigen Werte sortiert werden müssen). Und es stellt die CDF als eine Schrittfunktion dar, die es genau genommen ist.

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