diff --git a/episodes/03-transform.md b/episodes/03-transform.md
index d041c84e..147866a2 100644
--- a/episodes/03-transform.md
+++ b/episodes/03-transform.md
@@ -501,66 +501,9 @@ types can be awkward. It will be more convenient to choose one object and get al
data into it.
Now we can extract the columns we want from `skycoord_gd1` and add
-them as columns in the Astropy `Table` `polygon_results`. `phi1` and `phi2` contain the
+them to a Pandas `DataFrame`. `phi1` and `phi2` contain the
transformed coordinates.
-```python
-polygon_results['phi1'] = skycoord_gd1.phi1
-polygon_results['phi2'] = skycoord_gd1.phi2
-polygon_results.info()
-```
-
-```output
-
- name dtype unit description class
---------- ------- -------- ------------------------------------------------------------------ ------------
-source_id int64 Unique source identifier (unique within a particular Data Release) MaskedColumn
- ra float64 deg Right ascension MaskedColumn
- dec float64 deg Declination MaskedColumn
- pmra float64 mas / yr Proper motion in right ascension direction MaskedColumn
- pmdec float64 mas / yr Proper motion in declination direction MaskedColumn
- parallax float64 mas Parallax MaskedColumn
- phi1 float64 deg Column
- phi2 float64 deg Column
-```
-
-`pm_phi1_cosphi2` and `pm_phi2` contain the components of proper
-motion in the transformed frame.
-
-```python
-polygon_results['pm_phi1'] = skycoord_gd1.pm_phi1_cosphi2
-polygon_results['pm_phi2'] = skycoord_gd1.pm_phi2
-polygon_results.info()
-```
-
-```output
-
- name dtype unit description class
---------- ------- -------- ------------------------------------------------------------------ ------------
-source_id int64 Unique source identifier (unique within a particular Data Release) MaskedColumn
- ra float64 deg Right ascension MaskedColumn
- dec float64 deg Declination MaskedColumn
- pmra float64 mas / yr Proper motion in right ascension direction MaskedColumn
- pmdec float64 mas / yr Proper motion in declination direction MaskedColumn
- parallax float64 mas Parallax MaskedColumn
- phi1 float64 deg Column
- phi2 float64 deg Column
- pm_phi1 float64 mas / yr Column
- pm_phi2 float64 mas / yr Column
-```
-
-::::::::::::::::::::::::::::::::::::::::: callout
-
-Detail
-If you notice that `SkyCoord` has an attribute called
-`proper_motion`, you might wonder why we are not using it.
-
-We could have: `proper_motion` contains the same data as
-`pm_phi1_cosphi2` and `pm_phi2`, but in a different format.
-
-
-::::::::::::::::::::::::::::::::::::::::::::::::::
-
::::::::::::::::::::::::::::::::::::::::: callout
## Pandas `DataFrame`s versus Astropy `Table`s
@@ -604,7 +547,7 @@ results_df.shape
```
```output
-(140339, 10)
+(140339, 6)
```
It also provides `head`, which displays the first few rows. `head` is
@@ -614,6 +557,38 @@ useful for spot-checking large results as you go along.
results_df.head()
```
+```output
+ source_id ra dec pmra pmdec parallax
+0 637987125186749568 142.483019 21.757716 -2.516838 2.941813 -0.257345
+1 638285195917112960 142.254529 22.476168 2.662702 -12.165984 0.422728
+2 638073505568978688 142.645286 22.166932 18.306747 -7.950660 0.103640
+3 638086386175786752 142.577394 22.227920 0.987786 -2.584105 -0.857327
+4 638049655615392384 142.589136 22.110783 0.244439 -4.941079 0.099625
+
+```
+
+Now we can add the GD-1 coordinates and proper motions as columns in the
+`DataFrame`. We use the `.value` attribute to extract the numerical values
+without units, since Pandas `DataFrame`s do not preserve astropy units.
+
+```python
+results_df['phi1'] = skycoord_gd1.phi1.value
+results_df['phi2'] = skycoord_gd1.phi2.value
+results_df['pm_phi1'] = skycoord_gd1.pm_phi1_cosphi2.value
+results_df['pm_phi2'] = skycoord_gd1.pm_phi2.value
+results_df.shape
+```
+
+```output
+(140339, 10)
+```
+
+And we can check the result with `head`:
+
+```python
+results_df.head()
+```
+
```output
source_id ra dec pmra pmdec parallax phi1 phi2 pm_phi1 pm_phi2
0 637987125186749568 142.483019 21.757716 -2.516838 2.941813 -0.257345 -54.975623 -3.659349 6.429945 6.518157
@@ -626,6 +601,30 @@ results_df.head()
::::::::::::::::::::::::::::::::::::::::: callout
+## Why `.value`?
+
+The attributes of a `SkyCoord` object, like `phi1` and `phi2`,
+are `Quantity` objects that carry units (for example, degrees).
+Pandas `DataFrame`s do not support `Quantity` columns, so we use
+the `.value` attribute to extract the numerical values without units.
+
+
+::::::::::::::::::::::::::::::::::::::::::::::::::
+
+::::::::::::::::::::::::::::::::::::::::: callout
+
+Detail
+If you notice that `SkyCoord` has an attribute called
+`proper_motion`, you might wonder why we are not using it.
+
+We could have: `proper_motion` contains the same data as
+`pm_phi1_cosphi2` and `pm_phi2`, but in a different format.
+
+
+::::::::::::::::::::::::::::::::::::::::::::::::::
+
+::::::::::::::::::::::::::::::::::::::::: callout
+
## Attributes vs functions
`shape` is an attribute, so we display its value
@@ -649,7 +648,7 @@ to copy and paste the code over and over again.
```python
def make_dataframe(table):
- """Transform coordinates from ICRS to GD-1 frame.
+ """Transform and astropy table with coords in ICRS, convert to pandas dataframe with GD-1 coordinates.
table: Astropy Table
@@ -674,15 +673,15 @@ def make_dataframe(table):
# Correct GD-1 coordinates for solar system motion around galactic center
skycoord_gd1 = reflex_correct(transformed)
- #Add GD-1 reference frame columns for coordinates and proper motions
- table['phi1'] = skycoord_gd1.phi1
- table['phi2'] = skycoord_gd1.phi2
- table['pm_phi1'] = skycoord_gd1.pm_phi1_cosphi2
- table['pm_phi2'] = skycoord_gd1.pm_phi2
-
# Create DataFrame
df = table.to_pandas()
+ # Add GD-1 reference frame columns for coordinates and proper motions
+ df['phi1'] = skycoord_gd1.phi1.value
+ df['phi2'] = skycoord_gd1.phi2.value
+ df['pm_phi1'] = skycoord_gd1.pm_phi1_cosphi2.value
+ df['pm_phi2'] = skycoord_gd1.pm_phi2.value
+
return df
```
diff --git a/student_download/episode_functions.py b/student_download/episode_functions.py
index fb92c791..45b63a05 100644
--- a/student_download/episode_functions.py
+++ b/student_download/episode_functions.py
@@ -29,7 +29,7 @@ def skycoord_to_string(skycoord):
# Episode 3
##########################
def make_dataframe(table):
- """Transform coordinates from ICRS to GD-1 frame.
+ """Transform and astropy table with coords in ICRS, convert to pandas dataframe with GD-1 coordinates.
table: Astropy Table
@@ -54,15 +54,15 @@ def make_dataframe(table):
# Correct GD-1 coordinates for solar system motion around galactic center
skycoord_gd1 = reflex_correct(transformed)
- #Add GD-1 reference frame columns for coordinates and proper motions
- table['phi1'] = skycoord_gd1.phi1
- table['phi2'] = skycoord_gd1.phi2
- table['pm_phi1'] = skycoord_gd1.pm_phi1_cosphi2
- table['pm_phi2'] = skycoord_gd1.pm_phi2
-
# Create DataFrame
df = table.to_pandas()
+ # Add GD-1 reference frame columns for coordinates and proper motions
+ df['phi1'] = skycoord_gd1.phi1.value
+ df['phi2'] = skycoord_gd1.phi2.value
+ df['pm_phi1'] = skycoord_gd1.pm_phi1_cosphi2.value
+ df['pm_phi2'] = skycoord_gd1.pm_phi2.value
+
return df
##########################