2016-10-11 3 views
-1

Wenn ich folgende DatenArray von Hashes Probleme

First Name =>, Last Name, Age, Income, Household Size, Gender, Education 
Jon, Smith, 25, 50000, 1, Male, College 
Jane, Davies, 30, 60000, 3, Female, High School 
Sam, Farelly, 32, 80000, 2, Unspecified, College 
Joan, Favreau, 35, 65000, 4, Female, College 
Sam, McNulty, 38, 63000, 3, Male, College 
Mark, Minahan, 48, 78000, 5, Male, High School 
Susan, Umani, 45, 75000, 2, Female, College 
Bill, Perault, 24, 45000, 1, Male, Did Not Complete High School 
Doug, Stamper, 45, 75000, 1, Male, College 
Francis, Underwood, 52, 100000, 2, Male, College 

und ich möchte ein Array von Hashes erstellen, die folgenden Fragen Durchschnittsalter Durchschnittliches Einkommen Durchschnittliche Haushaltsgröße Weiblich Prozentsatz Männlich Prozentsatz zu beantworten Nicht angegeben Geschlechtsprozentsatz Prozent der Personen, die einen Hochschulabschluss erreicht haben Prozent der Personen, die einen Hochschulabschluss erworben haben Prozent der Befragten, die die High School nicht abgeschlossen haben

würde ich die Daten auf diese Weise konnte

voter_demographics = [ 
    { 
    :firstname => ["Jon", "Jane", "Sam", "Joan", "Sam", "Mark", "Susan", "Bill", "Doug", "Francis"], 
    :lastname => ["Smith", "Davies", "Farelly", "Favreau", "McNulty", "Minahan", "Umani", "Perault", "Stamper", "Underwood"], 
    :age => [25, 30, 32, 35, 38, 48, 45, 24, 45, 52], 
    :income => [50000, 60000, 80000, 65000, 63000, 78000, 75000, 45000, 75000, 100000], 
    :household_size => [1, 3, 2, 4, 3, 5, 2, 1, 1, 2], 
    :gender => ["male", "female", "unspecified", "female", "male", "male", "female", "male", "male", "male"], 
    :education => ["college", "high school", "college", "college", "college", "high school", "college", "did not complete high school", "college", "college"] 
    } 
] 

Wenn mich jemand einfach organisieren können, helfen ein (Durchschnittsalter) auf Frage beginnen. Ich kämpfe immer noch an Hashes und wie ich die Daten ausrufe.

For the first question ; Find Average age. Would the following work. 
sum = 0 
voter_demographics.each do |:age| 
sum = sum + :age 
average = sum/:age.length 
puts "The average is #{average}". 

Ich bin auf diesem fest. Und wenn es irgendwelche Ressourcen für Anfänger gibt, können Sie auf Hashes und Array von Hashes empfehlen, die großartig wären!

+1

'voter_demographics.first [: Alter] .instance_eval {inject (: +)/size}' –

+0

Willkommen bei Stack Overflow. Während wir mit der Aufgabe des Lernens betonen können, ist es _REIELL_ wichtig, dass Sie es versuchen, dann versuchen Sie es erneut und fahren Sie fort, bis Sie es nicht mehr versuchen können, wenn Sie mit Hausaufgaben oder selbst zugewiesenem Lernen zu tun haben. "[ask]", "[mcve]", "[Wie viel Forschungsaufwand wird von Stack Overflow-Benutzern erwartet?] (http://meta.stackoverflow.com/q/261592)". "Fragen, die nach Hausaufgaben fragen, müssen eine Zusammenfassung der bisherigen Arbeit enthalten, um das Problem zu lösen, und eine Beschreibung der Schwierigkeit, die Sie bei der Lösung des Problems haben." und http://meta.stackoverflow.com/questions/334822 –

Antwort

0

Ich frage mich, warum Sie voter_demographics haben als eine Anordnung. Wenn Sie die eckigen Klammern entfernen, dann wäre es nur ein Hash sein, wie folgt aus:

voter_demographics = { 
    :firstname => ["Jon", "Jane", "Sam", "Joan", "Sam", "Mark", "Susan", "Bill", "Doug", "Francis"], 
    :lastname => ["Smith", "Davies", "Farelly", "Favreau", "McNulty", "Minahan", "Umani", "Perault", "Stamper", "Underwood"], 
    :age => [25, 30, 32, 35, 38, 48, 45, 24, 45, 52], 
    :income => [50000, 60000, 80000, 65000, 63000, 78000, 75000, 45000, 75000, 100000], 
    :household_size => [1, 3, 2, 4, 3, 5, 2, 1, 1, 2], 
    :gender => ["male", "female", "unspecified", "female", "male", "male", "female", "male", "male", "male"], 
    :education => ["college", "high school", "college", "college", "college", "high school", "college", "did not complete high school", "college", "college"] 
} 

Dann können Sie Werte zugreifen in der Hash wie folgt aus:

voter_demographics[:age] 

Und Ihre durchschnittliche finden wie dies funktionieren würde :

voter_demographics[:age].inject(:+).to_f/voter_demographics[:age].size 

oder

ages = voter_demographics[:age] 
ages.inject(:+).to_f/ages.size 

Die .to_f geht davon aus, dass Sie eine Gleitkommazahl zurück haben möchten, sodass meine Lösungen Ihnen 37 geben würden.4 statt

Eine andere Lösung wäre, nur anstelle eines Hash reguläre Variablen verwenden:

firstnames = ["Jon", "Jane", "Sam", "Joan", "Sam", "Mark", "Susan", "Bill", "Doug", "Francis"], 
lastnames = ["Smith", "Davies", "Farelly", "Favreau", "McNulty", "Minahan", "Umani", "Perault", "Stamper", "Underwood"], 
ages = [25, 30, 32, 35, 38, 48, 45, 24, 45, 52], 
incomes = [50000, 60000, 80000, 65000, 63000, 78000, 75000, 45000, 75000, 100000], 
household_sizes = [1, 3, 2, 4, 3, 5, 2, 1, 1, 2], 
genders = ["male", "female", "unspecified", "female", "male", "male", "female", "male", "male", "male"], 
educations = ["college", "high school", "college", "college", "college", "high school", "college", "did not complete high school", "college", "college"] 

Dann würde diese Arbeit:

ages.inject(:+).to_f/ages.size 
0

Ihre voter_demographics ist ein Array mit nur einem Element

voter_demographics[0] 
=> {:firstname=>["Jon", "Jane", "Sam", "Joan", "Sam", "Mark", "Susan", "Bill", "Doug", "Francis"], :lastname=>["Smith", "Davies", "Farelly", "Favreau", "McNulty", "Minahan", "Umani", "Perault", "Stamper", "Underwood"], :age=>[25, 30, 32, 35, 38, 48, 45, 24, 45, 52], :income=>[50000, 60000, 80000, 65000, 63000, 78000, 75000, 45000, 75000, 100000], :household_size=>[1, 3, 2, 4, 3, 5, 2, 1, 1, 2], :gender=>["male", "female", "unspecified", "female", "male", "male", "female", "male", "male", "male"], :education=>["college", "high school", "college", "college", "college", "high school", "college", "did not complete high school", "college", "college"]} 
voter_demographics[1] 
=> nil 

So lassen Sie uns das erste Element nehmen und die Altersdaten erhalten:

age_data = voter_demographics[0][:age] 
=> [25, 30, 32, 35, 38, 48, 45, 24, 45, 52] 

Jetzt können wir die Daten zusammenzufassen

sum = 0 
age_data.each { |e| sum = sum + e } 
sum 
=> 374 

oder einfach

age_data.inject(:+) 
=> 374 

können Sie erhalten auch die Anzahl der Elemente

age_data.size 
=> 10 

Schließlich

age_data.inject(:+)/age_data.size 
=> 37 

Ich hoffe, es hilft Ihnen, es zu verstehen;)

1
keys, *data =<<_.split(/\n/).map { |line| line.split /,\s+/ } 
First Name, Last Name, Age, Income, Household Size, Gender, Education 
Jon, Smith, 25, 50000, 1, Male, College 
Jane, Davies, 30, 60000, 3, Female, High School 
Sam, Farelly, 32, 80000, 2, Unspecified, College 
Joan, Favreau, 35, 65000, 4, Female, College 
Sam, McNulty, 38, 63000, 3, Male, College 
Mark, Minahan, 48, 78000, 5, Male, High School 
Susan, Umani, 45, 75000, 2, Female, College 
Bill, Perault, 24, 45000, 1, Male, Did Not Complete High School 
Doug, Stamper, 45, 75000, 1, Male, College 
Francis, Underwood, 52, 100000, 2, Male, College 
_ 

Wir haben jetzt die folgenden Werte für keys und data.

keys 
    #=> ["First Name", "Last Name", "Age", "Income", "Household Size", 
    # "Gender", "Education"] 
data 
    #=> [["Jon", "Smith", "25", "50000", "1", "Male", "College"], 
    # ["Jane", "Davies", "30", "60000", "3", "Female", "High School"], 
    # ["Sam", "Farelly", "32", "80000", "2", "Unspecified", "College"], 
    # ["Joan", "Favreau", "35", "65000", "4", "Female", "College"], 
    # ["Sam", "McNulty", "38", "63000", "3", "Male", "College"], 
    # ["Mark", "Minahan", "48", "78000", "5", "Male", "High School"], 
    # ["Susan", "Umani", "45", "75000", "2", "Female", "College"], 
    # ["Bill", "Perault", "24", "45000", "1", "Male", "Did Not Complete High School"], 
    # ["Doug", "Stamper", "45", "75000", "1", "Male", "College"], 
    # ["Francis", "Underwood", "52", "100000", "2", "Male", "College"]] 

Als nächstes erstellen Sie den folgenden Hash.

h = keys.zip(data.transpose).to_h 
    #=> {"First Name" =>["Jon", "Jane", "Sam", "Joan", "Sam", "Mark", "Susan", 
    #      "Bill", "Doug", "Francis"], 
    # "Last Name"  =>["Smith", "Davies", "Farelly", "Favreau", "McNulty", "Minahan", 
    #      "Umani", "Perault", "Stamper", "Underwood"], 
    # "Age"   =>["25", "30", "32", "35", "38", "48", "45", "24", "45", "52"], 
    # "Income"  =>["50000", "60000", "80000", "65000", "63000", "78000", 
    #      "75000", "45000", "75000", "100000"], 
    # "Household Size"=>["1", "3", "2", "4", "3", "5", "2", "1", "1", "2"], 
    # "Gender"  =>["Male", "Female", "Unspecified", "Female", "Male", "Male", 
    #      "Female", "Male", "Male", "Male"], 
    # "Education"  =>["College", "High School", "College", "College", "College", 
    #      "High School", "College", "Did Not Complete High School", 
    #      "College", "College"]} 

Es ist jetzt einfach, die verschiedenen Statistiken zu berechnen.

n = arr.size.to_f 
    #=> 10.0 

avg_age = h["Age"].map(&:to_i).reduce(:+)/n.to_f 
    #=> 37.4 
avg_income = h["Income"].map(&:to_i).reduce(:+)/n.to_f 
    #=> 69100.0 
avg_hsize = h["Household Size"].map(&:to_i).reduce(:+)/n.to_f 
    #=> 2.4 
pct_female= 100*h["Gender"].count("Female")/n.to_f 
    #=> 30.0 

und so weiter.

Computing andere Statistiken

Angenommen, Sie wollten Statistiken berechnen, die mehrere Schlüssel, wie das Durchschnittsalter der Frauen beteiligt. Der einfachste Weg, dies zu tun (und die einfachen Mittelwerte und Prozentsätze zu berechnen), besteht darin, die Daten in eine Datenbank zu stellen und SQL-Abfragen zu verwenden. Wir können das aber auch, indem wir zuerst ein Array von Hashes erstellen.

arr = data.map { |row| keys.zip(row).to_h } 
    #=> [{"First Name"=>"Jon", "Last Name"=>"Smith", "Age"=>"25", "Income"=>"50000", 
    #  "Household Size"=>"1", "Gender"=>"Male", "Education"=>"College"}, 
    # {"First Name"=>"Jane", "Last Name"=>"Davies", "Age"=>"30", "Income"=>"60000", 
    #  "Household Size"=>"3", "Gender"=>"Female", "Education"=>"High School"}, 
    # {"First Name"=>"Sam", "Last Name"=>"Farelly", "Age"=>"32", "Income"=>"80000", 
    #  "Household Size"=>"2", "Gender"=>"Unspecified", "Education"=>"College"}, 
    # {"First Name"=>"Joan", "Last Name"=>"Favreau", "Age"=>"35", "Income"=>"65000", 
    #  "Household Size"=>"4", "Gender"=>"Female", "Education"=>"College"}, 
    # {"First Name"=>"Sam", "Last Name"=>"McNulty", "Age"=>"38", "Income"=>"63000", 
    #  "Household Size"=>"3", "Gender"=>"Male", "Education"=>"College"}, 
    # {"First Name"=>"Mark", "Last Name"=>"Minahan", "Age"=>"48", "Income"=>"78000", 
    #  "Household Size"=>"5", "Gender"=>"Male", "Education"=>"High School"}, 
    # {"First Name"=>"Susan", "Last Name"=>"Umani", "Age"=>"45", "Income"=>"75000", 
    #  "Household Size"=>"2", "Gender"=>"Female", "Education"=>"College"}, 
    # {"First Name"=>"Bill", "Last Name"=>"Perault", "Age"=>"24", "Income"=>"45000", 
    #  "Household Size"=>"1", "Gender"=>"Male", 
    #  "Education"=>"Did Not Complete High School"}, 
    # {"First Name"=>"Doug", "Last Name"=>"Stamper", "Age"=>"45", "Income"=>"75000", 
    #  "Household Size"=>"1", "Gender"=>"Male", "Education"=>"College"}, 
    # {"First Name"=>"Francis", "Last Name"=>"Underwood", "Age"=>"52", 
    #  "Income"=>"100000", "Household Size"=>"2", "Gender"=>"Male", 
    #  "Education"=>"College"}] 

dann das Durchschnittsalter von Frauen zu berechnen, ein Array von Alter für Frauen schaffen, dann seine Elemente summieren und diese Summe durch die Größe des Feldes unterteilt.

a = arr.each_with_object([]) { |h,a| a << h["Age"].to_i if h["Gender"]=="Female" } 
    #=> [30, 35, 45] 
a.empty? ? 0.0 : a.reduce(:+)/a.size.to_f 
    #=> 36.666666666666664 

Andere Berechnungen sind ähnlich.

0

Um den ersten Teil Ihrer Frage zu beantworten, wie Sie Ihre Daten in voter_demographics organisieren, können Sie einen csv-Parser in Ruby verwenden. Speichern Sie die Daten in einem Format file.csv, und analysieren Sie es.

require 'csv' 

csv_data = CSV.parse(File.read('file1.csv'), headers: true, header_converters: :symbol) 

data_array = csv_data.map {|arr| arr.to_h} 

Jetzt haben wir eine Reihe von Hashes wie

[{:first_name=>"Jon", :last_name=>" Smith", :age=>" 25", :income=>" 50000", :household_size=>" 1", :gender=>" Male", :education=>" College"}, 
{:first_name=>"Jane", :last_name=>" Davies", :age=>" 30", :income=>" 60000", :household_size=>" 3", :gender=>" Female", :education=>" High School"}, 
...] 

Jetzt haben wir etwas schreiben kann, diese Daten in das gewünschte Format zu formatieren.

result = {} 

data_array[0].each do |k, v| 
    result[k] = data_array.map {|hash| hash[k].strip } 
end 

Die anderen Antworten beantwortet bereits den zweiten Teil Ihrer Frage, also werde ich es hier nicht noch einmal tun.