6
$\begingroup$

I'm trying to use WeatherData[] to give me (not sure how) the temperature, humidity, wind-speed, cloud cover... at a certain location.

I only want the information for weekdays (e.g. Monday-Friday) for the last 83 years.

How do I make a list of all these dates in a format (DateList or DateString) that WeatherData[] can use?

$\endgroup$
  • 6
    $\begingroup$ Search for DayOfWeek in the documentation. $\endgroup$ – b.gates.you.know.what Jun 12 '12 at 13:28
5
$\begingroup$

For variation, here is method that doesn't require the Calendar package and uses a function which returns days of the week ranging from 0 for Sunday to 6 for Saturday:

GaussDay[y_Integer, m_Integer, d_Integer] := 
 With[{yDigits = IntegerDigits[y - Boole[m < 3]},
  With[{ y1 = FromDigits[yDigits[[1 ;; 2]]], 
    y2 = FromDigits[yDigits[[3 ;; 4]]]}, 
   Mod[(d + Floor[2.6 ( Mod[m + 9, 12] + 1) - 0.2] + y2 + 
      Quotient[y2, 4] + Quotient[y1, 4] - 2 y1), 7]]]

And in play:

Select[WeatherData["Chicago", 
  "Temperature", {{2011, 1, 1}, {2011, 12, 11}}], 
 MemberQ[Range@5, GaussDay @@ #[[1, 1 ;; 3]]] &]

For comparison, this took about 8.5 seconds to select approx 130,000 measurements when asked for 83 years of data.

$\endgroup$
  • $\begingroup$ Floor[y2/4] is better expressed as Quotient[y2, 4]. $\endgroup$ – J. M. will be back soon Jun 12 '12 at 15:53
  • 1
    $\begingroup$ This is a good solution. As a rule of thumb, never use Mathematica's built-in date functions unless you absolutely have to. By my tests, they are two orders of magnitude slower than Visual Basic's comparable functions, and even farther behind compiled languages. $\endgroup$ – Michael Stern Jun 12 '12 at 15:53
  • 3
    $\begingroup$ Also, I prefer Larsen's method myself for day-of-week computations: larsen[{yr_Integer, mo_Integer, da_Integer}] := Module[{y = yr, m = mo, d = da, f, q}, If[m < 3, y--; m += 12]; f = If[y >= 1752 && m >= 9 && d >= 14, Quotient[y, 400] - Quotient[y, 100], 5]; q = d + 2 m + 1 + Quotient[3 (m + 1), 5] + y + Quotient[y, 4] + f; Mod[q, 7] + 1]. No digit twiddling necessary; just integer arithmetic. $\endgroup$ – J. M. will be back soon Jun 12 '12 at 15:59
  • $\begingroup$ @J.M. Thank you. $\endgroup$ – image_doctor Jun 12 '12 at 16:00
  • 2
    $\begingroup$ If[m < 3, IntegerDigits[y - 1], IntegerDigits[y]] might be better written as IntegerDigits[y - Boole[m < 3]]. $\endgroup$ – J. M. will be back soon Jun 12 '12 at 16:01
4
$\begingroup$

After testing the performance of my first answer, along with J.M.'s suggestion, I don't think it will be fast enough. Here is another approach: filtering after acquisition.

This gives all "Temperature" data for Chicago in 2011, filtering out all Saturdays and Sundays.

Select[
  WeatherData["Chicago", "Temperature", {{2011, 1, 1}, {2011, 12, 31}}],
  ! MatchQ[DateString[#[[1]], "DayName"], "Saturday" | "Sunday"] &
]

If you only want one point for each day, use: {{2011, 1, 1}, {2011, 12, 31}, "Day"}

$\endgroup$
  • 3
    $\begingroup$ No need for the Calendar package. The built-in DateString[{2011, 1, 1}, {"DayName"}] will do (and is slightly faster too). Note that it returns day names as strings instead of symbols. $\endgroup$ – Sjoerd C. de Vries Jun 12 '12 at 21:03
  • $\begingroup$ @Sjoerd thanks! Updated. $\endgroup$ – Mr.Wizard Jun 12 '12 at 21:27
3
$\begingroup$

Load the Calendar package:

Needs["Calendar`"]

Find a Sunday:

DayOfWeek[{1950, 1, 1}] (* Sunday *)

Create a list of offsets from that day for weekdays:

weeks = 10;
offsets = Join @@ Array[Range@5 + 7 # &, weeks, 0];

Generate resolved days from offsets:

weekdays = DaysPlus[{1950, 1, 1}, #]& /@ offsets;

Confirm:

Tally[DayOfWeek /@ weekdays]
{{Monday, 10}, {Tuesday, 10}, {Wednesday, 10}, {Thursday, 10}, {Friday, 10}}
$\endgroup$
  • 2
    $\begingroup$ After which, OP can do something like Outer[WeatherData["Chicago", #1, #2] &, {"Temperature", "Humidity", "WindSpeed", "CloudCoverFraction"}, weekdays, 1]. $\endgroup$ – J. M. will be back soon Jun 12 '12 at 13:43
  • $\begingroup$ @J.M. I'll try this, thanks! $\endgroup$ – wizlog Jun 12 '12 at 13:44
  • $\begingroup$ @J.M. okay; I was leaving something for the OP to figure out. ;-) $\endgroup$ – Mr.Wizard Jun 12 '12 at 13:44
  • $\begingroup$ @Mr.Wizard I'm sure in the long run I'd appreciate it, but right now... No. (I'm just in a hurry.) $\endgroup$ – wizlog Jun 12 '12 at 13:46
  • 1
    $\begingroup$ Wizard: I figured that use of Outer[] is not too well-known among beginners, so I figured it should be pointed out... :) $\endgroup$ – J. M. will be back soon Jun 12 '12 at 13:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.