Skip to content

Commit 7b9ee2f

Browse files
authored
Add a new method to get related places. (#113)
* Add a new method to get related places. * fix indents
1 parent 540e746 commit 7b9ee2f

4 files changed

Lines changed: 90 additions & 15 deletions

File tree

datacommons/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
# Data Commons Python Client API
1919
from datacommons.core import get_property_labels, get_property_values, get_triples
20-
from datacommons.places import get_places_in
20+
from datacommons.places import get_places_in, get_related_places
2121
from datacommons.populations import get_populations, get_observations, get_pop_obs, get_place_obs
2222

2323
# Other utilities

datacommons/examples/places.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# you may not use this file except in compliance with the License.
55
# You may obtain a copy of the License at
66
#
7-
# http://www.apache.org/licenses/LICENSE-2.0
7+
# http://www.apache.org/licenses/LICENSE-2.0
88
#
99
# Unless required by applicable law or agreed to in writing, software
1010
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -22,6 +22,7 @@
2222

2323
import datacommons as dc
2424

25+
2526
def main():
2627
# Create a list of dcids for Santa Clara and Montgomery County.
2728
sc, mc = 'geoId/06085', 'geoId/24031'
@@ -39,5 +40,12 @@ def main():
3940
for dcid in tracts[mc][:10]:
4041
print(' - {}'.format(dcid))
4142

43+
# Get related places.
44+
print('Get related places')
45+
related_places = dc.get_related_places(['geoId/06085'], 'Person',
46+
{'age': "Years21To64", "gender": "Female"}, 'count', '')
47+
print(related_places)
48+
49+
4250
if __name__ == '__main__':
4351
main()

datacommons/places.py

Lines changed: 79 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# you may not use this file except in compliance with the License.
55
# You may obtain a copy of the License at
66
#
7-
# http://www.apache.org/licenses/LICENSE-2.0
7+
# http://www.apache.org/licenses/LICENSE-2.0
88
#
99
# Unless required by applicable law or agreed to in writing, software
1010
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -27,20 +27,20 @@
2727

2828
def get_places_in(dcids, place_type):
2929
""" Returns :obj:`Place`s contained in :code:`dcids` of type
30-
:code:`place_type`.
30+
:code:`place_type`.
3131
3232
Args:
3333
dcids (:obj:`iterable` of :obj:`str`): Dcids to get contained in places.
3434
place_type (:obj:`str`): The type of places contained in the given dcids to
35-
filter by.
35+
filter by.
3636
3737
Returns:
3838
The returned :obj:`Place`'s are formatted as a :obj:`dict` from a given
3939
dcid to a list of places identified by dcids of the given `place_type`.
4040
4141
Raises:
4242
ValueError: If the payload returned by the Data Commons REST API is
43-
malformed.
43+
malformed.
4444
4545
Examples:
4646
We would like to get all Counties contained in
@@ -49,15 +49,15 @@ def get_places_in(dcids, place_type):
4949
5050
>>> get_places_in(["geoId/06"], "County")
5151
{
52-
'geoId/06': [
53-
'geoId/06041',
54-
'geoId/06089',
55-
'geoId/06015',
56-
'geoId/06023',
57-
'geoId/06067',
58-
...
59-
# and 53 more
60-
]
52+
'geoId/06': [
53+
'geoId/06041',
54+
'geoId/06089',
55+
'geoId/06015',
56+
'geoId/06023',
57+
'geoId/06067',
58+
...
59+
# and 53 more
60+
]
6161
}
6262
"""
6363
dcids = list(dcids)
@@ -70,3 +70,69 @@ def get_places_in(dcids, place_type):
7070
# Create the results and format it appropriately
7171
result = utils._format_expand_payload(payload, 'place', must_exist=dcids)
7272
return result
73+
74+
75+
def get_related_places(dcids, population_type, constraining_properties={},
76+
measured_prop='count',
77+
stat_type='measured', within_place='',
78+
per_capita=False, same_place_type=False):
79+
""" Returns :obj:`Place`s related to :code:`dcids` for the given constraints.
80+
81+
Args:
82+
dcids (:obj:`iterable` of :obj:`str`): Dcids to get contained in places.
83+
population_type (:obj:`str`): The type of statistical population.
84+
constraining_properties (:obj:`map` from :obj:`str` to :obj:`str`, optional):
85+
A map from constraining property to the value that the
86+
:obj:`StatisticalPopulation` should be constrained by.
87+
measured_property (:obj:`str`): The measured property.
88+
stat_type (:obj:`str`): The statistical type for the observation.
89+
within_place(:obj:`str`): Optional, the place that all the related places
90+
are contained in.
91+
per_capita(:obj:`bool`): Optional, whether to take into account
92+
`PerCapita` when compute the relatedness.
93+
same_place_type(:obj:`bool`): Optional, whether to require all the
94+
related places under the same ancestor place.
95+
96+
Returns:
97+
The returned :obj:`Place`'s are formatted as a :obj:`dict` from a given
98+
dcid to a list of related places for the given constraints.
99+
100+
Raises:
101+
ValueError: If the payload returned by the Data Commons REST API is
102+
malformed.
103+
104+
Examples:
105+
We would like to get all related places of
106+
`Santa Clara county <https://browser.datacommons.org/kg?dcid=geoId/06085>`
107+
Specifying the :code:`dcids` as a :obj:`list` result in the following.
108+
109+
>>> get_places_in(["geoId/06"], "Person", {
110+
"age": "Years21To64",
111+
"gender": "Female"
112+
}, "count", "measured")
113+
{
114+
'geoId/06085': [
115+
'geoId/06041',
116+
'geoId/06089',
117+
'geoId/06015',
118+
'geoId/06023',
119+
]
120+
}
121+
"""
122+
dcids = list(dcids)
123+
url = utils._API_ROOT + utils._API_ENDPOINTS['get_related_places']
124+
pvs = []
125+
for p in constraining_properties:
126+
pvs.append({'property': p, 'value': constraining_properties[p]})
127+
req_json = {
128+
'dcids': dcids,
129+
'populationType': population_type,
130+
'pvs': pvs,
131+
'measuredProperty': measured_prop,
132+
'statType': '', # TODO: Set to stat_type when having it in BT data.
133+
'withinPlace': within_place,
134+
'perCapita': per_capita,
135+
'samePlaceType': same_place_type,
136+
}
137+
payload = utils._send_request(url, req_json=req_json)
138+
return payload

datacommons/utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
'get_property_values': '/node/property-values',
4343
'get_triples': '/node/triples',
4444
'get_places_in': '/node/places-in',
45+
'get_related_places': '/node/related-places',
4546
'get_populations': '/node/populations',
4647
'get_observations': '/node/observations',
4748
'get_pop_obs': '/bulk/pop-obs',

0 commit comments

Comments
 (0)