Ich habe eine Funktion, in der ich die ersten N Spalten eines DataFrame normalisieren. Ich möchte den normalisierten DataFrame zurückgeben, aber das Original in Ruhe lassen. Es scheint aber so, als ob die Funktion auch den übergebenen DataFrame mutiert!Julia: Übergabe eines DataFrame an eine Funktion erstellt einen Zeiger auf den DataFrame?
using DataFrames
function normalize(input_df::DataFrame, cols::Array{Int})
norm_df = input_df
for i in cols
norm_df[i] = (input_df[i] - minimum(input_df[i]))/
(maximum(input_df[i]) - minimum(input_df[i]))
end
norm_df
end
using RDatasets
iris = dataset("datasets", "iris")
println("original df:\n", head(iris))
norm_df = normalize(iris, [1:4]);
println("should be the same:\n", head(iris))
Ausgang:
original df:
6x5 DataFrame
| Row | SepalLength | SepalWidth | PetalLength | PetalWidth | Species |
|-----|-------------|------------|-------------|------------|----------|
| 1 | 5.1 | 3.5 | 1.4 | 0.2 | "setosa" |
| 2 | 4.9 | 3.0 | 1.4 | 0.2 | "setosa" |
| 3 | 4.7 | 3.2 | 1.3 | 0.2 | "setosa" |
| 4 | 4.6 | 3.1 | 1.5 | 0.2 | "setosa" |
| 5 | 5.0 | 3.6 | 1.4 | 0.2 | "setosa" |
| 6 | 5.4 | 3.9 | 1.7 | 0.4 | "setosa" |
should be the same:
6x5 DataFrame
| Row | SepalLength | SepalWidth | PetalLength | PetalWidth | Species |
|-----|-------------|------------|-------------|------------|----------|
| 1 | 0.222222 | 0.625 | 0.0677966 | 0.0416667 | "setosa" |
| 2 | 0.166667 | 0.416667 | 0.0677966 | 0.0416667 | "setosa" |
| 3 | 0.111111 | 0.5 | 0.0508475 | 0.0416667 | "setosa" |
| 4 | 0.0833333 | 0.458333 | 0.0847458 | 0.0416667 | "setosa" |
| 5 | 0.194444 | 0.666667 | 0.0677966 | 0.0416667 | "setosa" |
| 6 | 0.305556 | 0.791667 | 0.118644 | 0.125 | "setosa" |
Danke! In welchen Fällen wird also ein Objekt kopiert oder tief kopiert? Wenn ich zum Beispiel "iris2 = iris" mache und dann "iris2" an "normalize()" übergebe, sollte auch "iris" modifiziert werden? –
@AlexanderFlyax Ja, Iris würde geändert werden. Normalerweise erzeugt jede Operation der Form y = x * kein neues unabhängiges Objekt, unabhängig vom Typ (obwohl interessanterweise für Vektoren, y = x [1: end] '* wird * (denke ich), erzeuge ein unabhängiges Objekt). Für konkrete Typen wie 'Int64' erstellt 'copy' * * ein neues unabhängiges Objekt, aber für' Array {Int64} 'erstellt' copy' nur eine unabhängige äußere Struktur, aber keine unabhängigen internen Elemente, daher die Notwendigkeit für ' decopy beim Umgang mit Arrays. 'DataFrame' ist Array-ähnlich, und daher wird 'deepcopy' benötigt. –
Danke für Ihre Erklärung.Ich versuche nicht, Julia kritisch gegenüberzustehen, ich versuche nur zu verstehen: Warum sollte ich eine Kopie eines Arrays erstellen, wenn das Ändern der Kopie das ursprüngliche Array verändert? Wenn ich das ursprüngliche Array ändern wollte, würde ich das einfach tun, oder? Es scheint im besten Fall überflüssig und im schlimmsten Fall kontraproduktiv zu sein. Fehle ich etwas? –