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()
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 ()
Der Vollständigkeit halber sollten Sie auch Folgendes berücksichtigen:
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:
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()
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
Als schnelle Antwort
plt.plot(sorted_data, np.linspace(0,1,sorted_data.size)
hätte dich bekommen, was du wolltest
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)