Code
import numpy as np
import pandas as pd
import plotly.express as px
import scipy.stats as stats
from data_viz import *
from hypothesis_functions import *
Rebekah Chuang
December 5, 2023
The data, collected and provided by the City of Austin, Texas, spans from October 1st, 2013, to the present day (updated daily). These datasets comprehensively track the journey of animals from intake to eventual adoption, including those still awaiting adoption. The analysis explores animal adoption trends, rates, influencing factors, and variations in meeting the 90% save rate benchmark on a monthly basis. It assesses adoption rates based on various factors such as age, health conditions, and the impact of external factors, such as the onset of COVID-19, on adoption rates.
This page showcases the results of hypotheses and research questions derived from this analysis. For a comprehensive view, including fetching data using API endpoints, merging datasets, data cleaning, and visualization code, you can explore my Github repository.
# run this if env already exists
library(reticulate)
use_virtualenv("my_python_env")
animal_id | name | animal_type | sex_intake | sex_outcome | breed | color | date_of_birth | found_location | intake_datetime | outcome_datetime | intake_type | intake_condition | outcome_type | outcome_subtype | age_upon_intake(years) | age_upon_outcome(years) | duration(days) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | A006100 | Scamp | Dog | Neutered Male | Neutered Male | Spinone Italiano Mix | Yellow/White | 2007-07-09 | 8700 Research in Austin (TX) | 2014-03-07 14:26:00 | 2014-03-08 17:10:00 | Public Assist | Normal | Return to Owner | NaN | 6.7 | 6.7 | 1.0 |
1 | A006100 | Scamp | Dog | Neutered Male | Neutered Male | Spinone Italiano Mix | Yellow/White | 2007-07-09 | 8700 Research Blvd in Austin (TX) | 2014-12-19 10:21:00 | 2014-12-20 16:35:00 | Public Assist | Normal | Return to Owner | NaN | 7.4 | 7.4 | 1.0 |
2 | A006100 | Scamp | Dog | Neutered Male | Neutered Male | Spinone Italiano Mix | Yellow/White | 2007-07-09 | Colony Creek And Hunters Trace in Austin (TX) | 2017-12-07 14:07:00 | 2017-12-07 00:00:00 | Stray | Normal | Return to Owner | NaN | 10.4 | 10.4 | -1.0 |
3 | A047759 | Oreo | Dog | Neutered Male | Neutered Male | Dachshund | Tricolor | 2004-04-02 | Austin (TX) | 2014-04-02 15:55:00 | 2014-04-07 15:12:00 | Owner Surrender | Normal | Transfer | Partner | 10.0 | 10.0 | 4.0 |
4 | A134067 | Bandit | Dog | Neutered Male | Neutered Male | Shetland Sheepdog | Brown/White | 1997-10-16 | 12034 Research Blvd in Austin (TX) | 2013-11-16 09:02:00 | 2013-11-16 11:54:00 | Public Assist | Injured | Return to Owner | NaN | 16.1 | 16.1 | 0.0 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
157783 | A894540 | A894540 | Dog | Intact Male | NaN | Blue Lacy Mix | Blue/White | NaN | Rutlan And North Lamar in Austin (TX) | 2023-12-11 11:24:00 | NaN | Stray | Normal | NaN | NaN | NaN | NaN | NaN |
157784 | A894541 | A894541 | Cat | Intact Female | NaN | Domestic Shorthair Mix | Black | NaN | 2439 Town Lake Circle in Austin (TX) | 2023-12-11 12:12:00 | NaN | Stray | Normal | NaN | NaN | NaN | NaN | NaN |
157785 | A894547 | A894547 | Dog | Intact Female | NaN | Boxer Mix | Brown/White | NaN | 6200 Stiles Cove in Austin (TX) | 2023-12-11 12:59:00 | NaN | Stray | Normal | NaN | NaN | NaN | NaN | NaN |
157786 | A894551 | A894551 | Cat | Intact Female | NaN | Domestic Shorthair Mix | Tortie | NaN | 3002 Cheviot Lane in Austin (TX) | 2023-12-11 13:20:00 | NaN | Stray | Normal | NaN | NaN | NaN | NaN | NaN |
157787 | A894558 | NaN | Dog | Intact Female | NaN | Staffordshire Mix | White/Black | NaN | 5301 Decker Lane in Austin (TX) | 2023-12-11 15:27:00 | NaN | Stray | Normal | NaN | NaN | NaN | NaN | NaN |
157788 rows × 18 columns
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 157788 entries, 0 to 157787
Data columns (total 18 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 animal_id 157788 non-null object
1 name 112350 non-null object
2 animal_type 157788 non-null object
3 sex_intake 157786 non-null object
4 sex_outcome 156812 non-null object
5 breed 157788 non-null object
6 color 157788 non-null object
7 date_of_birth 156814 non-null object
8 found_location 157788 non-null object
9 intake_datetime 157788 non-null object
10 outcome_datetime 156814 non-null object
11 intake_type 157788 non-null object
12 intake_condition 157788 non-null object
13 outcome_type 156783 non-null object
14 outcome_subtype 72131 non-null object
15 age_upon_intake(years) 156814 non-null float64
16 age_upon_outcome(years) 156814 non-null float64
17 duration(days) 156814 non-null float64
dtypes: float64(3), object(15)
memory usage: 21.7+ MB
sex_type_freq = pd.merge(sex_type_intake_freq, sex_type_outcome_freq,
left_on = "sex_intake",
right_on = "sex_outcome",
suffixes = ["_intake", "_outcome"])
sex_type_freq.drop(columns=['sex_outcome'], inplace=True)
sex_type_freq.rename(columns = {"sex_intake":"sex"}, inplace=True)
# sex_type_freq
fig = px.bar(sex_type_freq,
x="sex",
y=["count_intake", "count_outcome"],
barmode="group",
labels={"sex": "Sex", "value": "Count", "variable": "Category"},
title="Count of Intake and Outcome by Sex")
fig.update_traces(name="Intake",
text=sex_type_freq["count_intake"],
textposition="outside",
selector=dict(name="count_intake"),
marker=dict(color="#13294B"))
fig.update_traces(name="Outcome",
text=sex_type_freq["count_outcome"],
textposition="outside",
selector=dict(name="count_outcome"),
marker=dict(color="#E84A27"))
fig.update_layout(title_x=0.5,
height=600,
width=1000)
fig.show()
Is there a correlation between the neuter/spay rate of animals and their age?
While there isn’t a specific age limit for the spaying or neutering procedure, the recommended timeframe for dogs or cats is typically between six to nine months. Concerns may arise regarding the risks associated with surgery in older animals. Additionally, if an animal hasn’t exhibited behavioral issues related to mating behaviors or health problems linked to remaining intact, some owners might perceive less urgency in proceeding with the surgery.
outcome_type
Adoption 73997
Transfer 44944
Return to Owner 24440
Euthanasia 9967
Died 1470
Rto-Adopt 1082
Disposal 768
Missing 84
Relocate 26
Stolen 5
Name: count, dtype: int64
alive_outcome_type = ["Euthanasia", "Died", "Disposal", "Missing", "Stolen"]
sex_change = data[(data["animal_type"].isin(["Dog", "Cat"])) &
(data["sex_intake"].isin(["Intact Female", "Intact Male"])) &
(~data["outcome_type"].isin(alive_outcome_type)) &
(~data["age_upon_outcome(years)"].isna())]\
[["animal_id", "animal_type", "sex_intake", "sex_outcome", "age_upon_outcome(years)", "outcome_datetime", "duration(days)", "outcome_type"]].reset_index(drop=True)
# add neutered_spayed_or_not column
sex_change["neutered_spayed_or_not"] = np.where(sex_change["sex_outcome"].isin(["Neutered Male", "Spayed Female"]), 1, 0)
sex_change
animal_id | animal_type | sex_intake | sex_outcome | age_upon_outcome(years) | outcome_datetime | duration(days) | outcome_type | neutered_spayed_or_not | |
---|---|---|---|---|---|---|---|---|---|
0 | A163459 | Dog | Intact Female | Intact Female | 15.1 | 2014-11-14 19:28:00 | 0.0 | Return to Owner | 0 |
1 | A191351 | Cat | Intact Female | Intact Female | 16.2 | 2015-11-17 13:29:00 | 3.0 | Return to Owner | 0 |
2 | A212672 | Dog | Intact Female | Intact Female | 13.8 | 2013-12-06 14:34:00 | 10.0 | Return to Owner | 0 |
3 | A256412 | Dog | Intact Male | Intact Male | 16.6 | 2013-10-06 14:26:00 | 0.0 | Return to Owner | 0 |
4 | A309829 | Dog | Intact Male | Intact Male | 13.0 | 2014-11-12 15:34:00 | 2.0 | Return to Owner | 0 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
97614 | A894297 | Dog | Intact Male | Intact Male | 2.0 | 2023-12-06 19:24:00 | 0.0 | Transfer | 0 |
97615 | A894324 | Dog | Intact Male | Intact Male | 0.5 | 2023-12-08 14:52:00 | 1.0 | Transfer | 0 |
97616 | A894377 | Cat | Intact Female | Intact Female | 1.0 | 2023-12-08 15:26:00 | 1.0 | Transfer | 0 |
97617 | A894389 | Dog | Intact Male | Intact Male | 10.0 | 2023-12-09 12:55:00 | 1.0 | Return to Owner | 0 |
97618 | A894500 | Dog | Intact Male | Intact Male | 1.0 | 2023-12-10 12:43:00 | 0.0 | Transfer | 0 |
97619 rows × 9 columns
neutered_n_spayed_count = sex_change.neutered_spayed_or_not.sum()
animal_count = sex_change.animal_id.count()
neutered_n_spayed_pct = neutered_n_spayed_count/animal_count
print(f"{round(neutered_n_spayed_pct, 3)*100.0}% of the animals that were intact before have been neutered/spayed upon outcome.")
64.0% of the animals that were intact before have been neutered/spayed upon outcome.
The Independent Samples T-Test is employed to compare the means of ages between two independent groups (neutered/spayed or not). This test helps define whether a significant difference exists in age between these two distinct groups.
T-Statistic: -27.800901329031614
P-Value: 1.9453487884732793e-169
The Chi-Squared Test is utilized to ascertain whether an association exists between two categorical variables (age group and neutered/spayed status). This test evaluates the relationship between these categorical variables to determine if they are associated or independent of each other.
animal_id | animal_type | sex_intake | sex_outcome | age_upon_outcome(years) | outcome_datetime | duration(days) | outcome_type | neutered_spayed_or_not | age_group | |
---|---|---|---|---|---|---|---|---|---|---|
0 | A163459 | Dog | Intact Female | Intact Female | 15.1 | 2014-11-14 19:28:00 | 0.0 | Return to Owner | 0 | Senior |
1 | A191351 | Cat | Intact Female | Intact Female | 16.2 | 2015-11-17 13:29:00 | 3.0 | Return to Owner | 0 | Senior |
2 | A212672 | Dog | Intact Female | Intact Female | 13.8 | 2013-12-06 14:34:00 | 10.0 | Return to Owner | 0 | Senior |
3 | A256412 | Dog | Intact Male | Intact Male | 16.6 | 2013-10-06 14:26:00 | 0.0 | Return to Owner | 0 | Senior |
4 | A309829 | Dog | Intact Male | Intact Male | 13.0 | 2014-11-12 15:34:00 | 2.0 | Return to Owner | 0 | Senior |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
97614 | A894297 | Dog | Intact Male | Intact Male | 2.0 | 2023-12-06 19:24:00 | 0.0 | Transfer | 0 | Young |
97615 | A894324 | Dog | Intact Male | Intact Male | 0.5 | 2023-12-08 14:52:00 | 1.0 | Transfer | 0 | Young |
97616 | A894377 | Cat | Intact Female | Intact Female | 1.0 | 2023-12-08 15:26:00 | 1.0 | Transfer | 0 | Young |
97617 | A894389 | Dog | Intact Male | Intact Male | 10.0 | 2023-12-09 12:55:00 | 1.0 | Return to Owner | 0 | Senior |
97618 | A894500 | Dog | Intact Male | Intact Male | 1.0 | 2023-12-10 12:43:00 | 0.0 | Transfer | 0 | Young |
97619 rows × 10 columns
neutered_spayed_or_not | 0 | 1 |
---|---|---|
age_group | ||
Young | 29165 | 52646 |
Adult | 4366 | 9131 |
Senior | 1573 | 730 |
age_groups = ["Young", "Adult", "Senior"]
for age_group in age_groups:
total = neuter_spay_age_contingency_table.loc[age_group].sum()
neuter_spay_count = neuter_spay_age_contingency_table.loc[age_group, 1]
neuter_spay_rate = round(neuter_spay_count/total, 4)*100.0
print(f"The neuter/spay rate for {age_group.lower()} dogs/cats is {neuter_spay_rate}%")
The neuter/spay rate for young dogs/cats is 64.35%
The neuter/spay rate for adult dogs/cats is 67.65%
The neuter/spay rate for senior dogs/cats is 31.7%
chi2, p, dof, expected = stats.chi2_contingency(neuter_spay_age_contingency_table)
print(f"chi2: {chi2}")
print(f"p-value: {p}")
print(f"dof: {dof}")
print(f"expected:\n{expected}")
# set significance level = 0.05
alpha = 0.05
if p < alpha:
print("\nThere is a significant relationship between age and neutered/spayed status.")
else:
print("\nThere is no significant relationship between age and neutered/spayed status.")
chi2: 1125.9288581014591
p-value: 3.218510686406676e-245
dof: 2
expected:
[[29421.82073742 52389.17926258]
[ 4853.94769032 8643.05230968]
[ 828.23157226 1474.76842774]]
There is a significant relationship between age and neutered/spayed status.
fig = px.histogram(sex_change,
x="age_group",
color="neutered_spayed_or_not",
barmode="group",
title="Neutered/Spayed Cases by Age Group")
fig.update_layout(title_x=0.5,
xaxis=dict(title="Age Group"),
yaxis=dict(title="Counts"),
legend_title_text="Neutered/Spayed Status",
height=600,
width=1000)
fig.update_layout(legend=dict(orientation="v",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1))
fig.show()
Has there been a significant change in the adoption rate of animals before and after the onset of COVID-19?
With more individuals spending extended periods at home due to lockdowns and remote work scenarios, there might have been an increased desire for companionship, potentially leading to a higher demand for pets
adoption_research = data[["animal_id", "outcome_datetime", "outcome_type"]].reset_index(drop=True)
adoption_research = adoption_research.dropna(subset=["outcome_datetime"])
adoption_research["adoption_status"] = np.where(adoption_research["outcome_type"] == "Adoption", "Adopted", "Not Adopted")
datetime_threshold = "2020-01-01"
adoption_research["before_or_after_covid"] = np.where(adoption_research["outcome_datetime"] < datetime_threshold, "pre-covid", "post-covid")
adoption_research
animal_id | outcome_datetime | outcome_type | adoption_status | before_or_after_covid | |
---|---|---|---|---|---|
0 | A006100 | 2014-03-08 17:10:00 | Return to Owner | Not Adopted | pre-covid |
1 | A006100 | 2014-12-20 16:35:00 | Return to Owner | Not Adopted | pre-covid |
2 | A006100 | 2017-12-07 00:00:00 | Return to Owner | Not Adopted | pre-covid |
3 | A047759 | 2014-04-07 15:12:00 | Transfer | Not Adopted | pre-covid |
4 | A134067 | 2013-11-16 11:54:00 | Return to Owner | Not Adopted | pre-covid |
... | ... | ... | ... | ... | ... |
157763 | A894445 | 2023-12-10 15:45:00 | Adoption | Adopted | post-covid |
157768 | A894472 | 2023-12-11 07:46:00 | Transfer | Not Adopted | post-covid |
157773 | A894500 | 2023-12-10 12:43:00 | Transfer | Not Adopted | post-covid |
157774 | A894504 | 2023-12-11 12:39:00 | Return to Owner | Not Adopted | post-covid |
157776 | A894514 | 2023-12-11 08:40:00 | Euthanasia | Not Adopted | post-covid |
156814 rows × 5 columns
adoption_status | Adopted | Not Adopted |
---|---|---|
before_or_after_covid | ||
post-covid | 24716 | 19476 |
pre-covid | 49281 | 63341 |
The adoption rate post-covid is 55.93%
The adoption rate pre-covid is 43.76%
chi2, p, dof, expected = stats.chi2_contingency(adoption_contingency_table)
print(f"chi2: {chi2}")
print(f"p-value: {p}")
print(f"dof: {dof}")
print(f"expected:\n{expected}")
# set significance level = 0.05
alpha = 0.05
if p < alpha:
print("\nThere is a significant increase in the adoption rate post-COVID compared to pre-COVID.")
else:
print("\nThere is no significant increase in the adoption rate post-COVID compared to pre-COVID.")
chi2: 1886.008048757299
p-value: 0.0
dof: 1
expected:
[[20853.21096331 23338.78903669]
[53143.78903669 59478.21096331]]
There is a significant increase in the adoption rate post-COVID compared to pre-COVID.
fig = px.histogram(adoption_research,
x="before_or_after_covid",
color="adoption_status",
barmode = "group",
title="Adoption Cases Before and After Covid")
fig.update_layout(title_x=0.5,
xaxis=dict(title="Adoption Status"),
yaxis=dict(title="Counts"),
legend_title_text="Adoption Status",
height=600,
width=1000)
fig.update_layout(legend=dict(
orientation="v",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1))
fig.show()
Does intake condition influence the probability of adoption for animals?
Typically, healthy animals often experience a higher likelihood of swift adoption, whereas those requiring extensive medical attention, facing chronic health issues, or exhibiting challenging behaviors might encounter prolonged waiting periods before finding homes.
abnormal_cond = ["Injured", "Sick", "Nursing", "Neonatal", "Aged", "Medical",
"Feral", "Pregnant", "Behavior", "Med Attn", "Med Urgent",
"Neurologic", "Space", "Parvo", "Agonal", "Panleuk", "Congenital"]
condition_research = data[~data["intake_condition"].isin(["Other", "Unknown"])]\
[["animal_id", "intake_condition", "outcome_type"]].reset_index(drop=True)
# add intake_cond_binary column
condition_research["intake_cond_binary"] = np.where(condition_research["intake_condition"].isin(abnormal_cond), "Non-Normal", "Normal")
# add adoption_status column
condition_research["adoption_status"] = np.where(condition_research["outcome_type"]=="Adoption", "Adopted", "Not Adopted")
condition_research
animal_id | intake_condition | outcome_type | intake_cond_binary | adoption_status | |
---|---|---|---|---|---|
0 | A006100 | Normal | Return to Owner | Normal | Not Adopted |
1 | A006100 | Normal | Return to Owner | Normal | Not Adopted |
2 | A006100 | Normal | Return to Owner | Normal | Not Adopted |
3 | A047759 | Normal | Transfer | Normal | Not Adopted |
4 | A134067 | Injured | Return to Owner | Non-Normal | Not Adopted |
... | ... | ... | ... | ... | ... |
157427 | A894540 | Normal | NaN | Normal | Not Adopted |
157428 | A894541 | Normal | NaN | Normal | Not Adopted |
157429 | A894547 | Normal | NaN | Normal | Not Adopted |
157430 | A894551 | Normal | NaN | Normal | Not Adopted |
157431 | A894558 | Normal | NaN | Normal | Not Adopted |
157432 rows × 5 columns
adoption_status | Adopted | Not Adopted |
---|---|---|
intake_cond_binary | ||
Non-Normal | 5987 | 16629 |
Normal | 67872 | 66944 |
condition_list = ["Non-Normal", "Normal"]
for condition in condition_list:
total = condition_adoption_contingency_table.loc[condition].sum()
adoption_cnt = condition_adoption_contingency_table.loc[condition, "Adopted"]
adoption_rate = round(adoption_cnt/total, 3)*100.0
print(f"{adoption_rate}% of animal whose intake condition were {condition.lower()} have been adopted.")
26.5% of animal whose intake condition were non-normal have been adopted.
50.3% of animal whose intake condition were normal have been adopted.
chi2, p, dof, expected = stats.chi2_contingency(condition_adoption_contingency_table)
print(f"chi2: {chi2}")
print(f"p-value: {p}")
print(f"dof: {dof}")
print(f"expected:\n{expected}")
# set significance level = 0.05
alpha = 0.05
if p < alpha:
print("\nThere is a significant relationship between the intake condition of animals at the shelter and their likelihood of adoption.")
else:
print("\nThere is no significant relationship between the intake condition of animals at the shelter and their likelihood of adoption.")
chi2: 4430.532316853005
p-value: 0.0
dof: 1
expected:
[[10610.26439352 12005.73560648]
[63248.73560648 71567.26439352]]
There is a significant relationship between the intake condition of animals at the shelter and their likelihood of adoption.
fig = px.histogram(condition_research,
x="intake_cond_binary",
color="adoption_status",
barmode = "group",
title="Adoption Status by Intake Condition")
fig.update_layout(title_x=0.5,
xaxis=dict(title="Adoption Status"),
yaxis=dict(title="Counts"),
legend_title_text="Adoption Status",
height=600,
width=1000)
fig.update_layout(legend=dict(
orientation="v",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1))
fig.show()
Does age influence the probability of adoption for animals?
An animal’s age could potentially impact its likelihood of adoption. Generally, most people tend to prefer younger animals as they are often perceived as more trainable. Younger animals haven’t developed habits, making them easier to train. Additionally, they offer longer companionship and possess more energy.
age_adoption_research = data[data["age_upon_outcome(years)"] >= 0][["animal_id", "outcome_type", "age_upon_outcome(years)"]].reset_index(drop=True)
age_adoption_research.loc[:, "age_group"] = pd.cut(age_adoption_research["age_upon_outcome(years)"],
bins=[-0.01, 2, 7, float('inf')],
labels=["Young", "Adult", "Senior"])
age_adoption_research["adoption_status"] = np.where(age_adoption_research["outcome_type"] == "Adoption", "Adopted", "Not Adopted")
age_adoption_research
animal_id | outcome_type | age_upon_outcome(years) | age_group | adoption_status | |
---|---|---|---|---|---|
0 | A006100 | Return to Owner | 6.7 | Adult | Not Adopted |
1 | A006100 | Return to Owner | 7.4 | Senior | Not Adopted |
2 | A006100 | Return to Owner | 10.4 | Senior | Not Adopted |
3 | A047759 | Transfer | 10.0 | Senior | Not Adopted |
4 | A134067 | Return to Owner | 16.1 | Senior | Not Adopted |
... | ... | ... | ... | ... | ... |
156784 | A894445 | Adoption | 1.5 | Young | Adopted |
156785 | A894472 | Transfer | 2.0 | Young | Not Adopted |
156786 | A894500 | Transfer | 1.0 | Young | Not Adopted |
156787 | A894504 | Return to Owner | 17.0 | Senior | Not Adopted |
156788 | A894514 | Euthanasia | 2.0 | Young | Not Adopted |
156789 rows × 5 columns
The Independent Samples T-Test is employed to compare the means of ages between two independent groups (being adopted or not). This test helps define whether a significant difference exists in age between these two distinct groups.
T-Statistic: -55.12214842454163
P-Value: 0.0
The Chi-Squared Test is utilized to ascertain whether an association exists between two categorical variables (age group and adoption status). This test evaluates the relationship between these categorical variables to determine if they are associated or independent of each other.
adoption_status | Adopted | Not Adopted |
---|---|---|
age_group | ||
Young | 55851 | 56359 |
Adult | 14234 | 18409 |
Senior | 3903 | 8033 |
age_groups = ["Young", "Adult", "Senior"]
for age_group in age_groups:
total = age_adoption_contingency_table.loc[age_group].sum()
adoption_count = age_adoption_contingency_table.loc[age_group, "Adopted"]
adoption_count_rate = round(adoption_count/total, 4)*100.0
print(f"The adoption rate for {age_group.lower()} dogs/cats is {adoption_count_rate}%")
The adoption rate for young dogs/cats is 49.769999999999996%
The adoption rate for adult dogs/cats is 43.61%
The adoption rate for senior dogs/cats is 32.7%
chi2, p, dof, expected = stats.chi2_contingency(age_adoption_contingency_table)
print(f"chi2: {chi2}")
print(f"p-value: {p}")
print(f"dof: {dof}")
print(f"expected:\n{expected}")
# set significance level = 0.05
alpha = 0.05
if p < alpha:
print("\nThere is a significant relationship between age and adoption status.")
else:
print("\nThere is no significant relationship between age and adoption status.")
chi2: 1474.593471046482
p-value: 0.0
dof: 2
expected:
[[52951.37720121 59258.62279879]
[15404.07990356 17238.92009644]
[ 5632.54289523 6303.45710477]]
There is a significant relationship between age and adoption status.
fig = px.histogram(age_adoption_research,
x="age_group",
color="adoption_status",
barmode = "group",
title="Adoption Status by Intake Condition")
fig.update_layout(title_x=0.5,
xaxis=dict(title="Adoption Status"),
yaxis=dict(title="Counts"),
legend_title_text="Adoption Status",
height=600,
width=1000)
fig.update_layout(legend=dict(
orientation="v",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1))
fig.show()
Does the city of Austin maintain a save rate of 90%
or higher for animals, thereby meeting the criteria to be classified as a no-kill city
?
Austin stands as one of the largest no-kill cities in America. According to the City of Austin, annually, over 90% of animals entering the center are either adopted, transferred to rescues, or returned to their owners. The research question aims to ascertain whether the Austin Animal Center meets this requirement or not.
outcome_type
Adoption 73997
Transfer 44944
Return to Owner 24440
Euthanasia 9967
Died 1470
Rto-Adopt 1082
Disposal 768
Missing 84
Relocate 26
Stolen 5
Name: count, dtype: int64
animal_id | intake_datetime | outcome_datetime | outcome_type | duration(days) | intake_y_m | outcome_y_m | intake_yr | outcome_yr | intake_m | outcome_m | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | A006100 | 2014-03-07 14:26:00 | 2014-03-08 17:10:00 | Return to Owner | 1.0 | 2014-03 | 2014-03 | 2014 | 2014 | March | March |
1 | A006100 | 2014-12-19 10:21:00 | 2014-12-20 16:35:00 | Return to Owner | 1.0 | 2014-12 | 2014-12 | 2014 | 2014 | December | December |
2 | A006100 | 2017-12-07 14:07:00 | 2017-12-07 00:00:00 | Return to Owner | -1.0 | 2017-12 | 2017-12 | 2017 | 2017 | December | December |
3 | A047759 | 2014-04-02 15:55:00 | 2014-04-07 15:12:00 | Transfer | 4.0 | 2014-04 | 2014-04 | 2014 | 2014 | April | April |
4 | A134067 | 2013-11-16 09:02:00 | 2013-11-16 11:54:00 | Return to Owner | 0.0 | 2013-11 | 2013-11 | 2013 | 2013 | November | November |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
157783 | A894540 | 2023-12-11 11:24:00 | NaT | NaN | NaN | 2023-12 | NaT | 2023 | NaT | December | NaN |
157784 | A894541 | 2023-12-11 12:12:00 | NaT | NaN | NaN | 2023-12 | NaT | 2023 | NaT | December | NaN |
157785 | A894547 | 2023-12-11 12:59:00 | NaT | NaN | NaN | 2023-12 | NaT | 2023 | NaT | December | NaN |
157786 | A894551 | 2023-12-11 13:20:00 | NaT | NaN | NaN | 2023-12 | NaT | 2023 | NaT | December | NaN |
157787 | A894558 | 2023-12-11 15:27:00 | NaT | NaN | NaN | 2023-12 | NaT | 2023 | NaT | December | NaN |
157788 rows × 11 columns
time | total_intake | total_outcome | euthanasia_cases | total_death_cases | save_rate(total death) | save_rate(euthanasia) | |
---|---|---|---|---|---|---|---|
0 | 2013-10 | 1589.0 | 1126 | 147 | 162 | 89.804909 | 90.748899 |
1 | 2013-11 | 1323.0 | 1213 | 120 | 129 | 90.249433 | 90.929705 |
2 | 2013-12 | 1270.0 | 1431 | 163 | 171 | 86.535433 | 87.165354 |
3 | 2014-01 | 1271.0 | 1224 | 114 | 124 | 90.243902 | 91.030685 |
4 | 2014-02 | 1192.0 | 1115 | 144 | 155 | 86.996644 | 87.919463 |
... | ... | ... | ... | ... | ... | ... | ... |
118 | 2023-08 | 965.0 | 1108 | 31 | 56 | 94.196891 | 96.787565 |
119 | 2023-09 | 927.0 | 874 | 33 | 46 | 95.037756 | 96.440129 |
120 | 2023-10 | 960.0 | 843 | 35 | 45 | 95.312500 | 96.354167 |
121 | 2023-11 | 761.0 | 833 | 36 | 56 | 92.641261 | 95.269382 |
122 | 2023-12 | 247.0 | 275 | 4 | 6 | 97.570850 | 98.380567 |
123 rows × 7 columns
time | total_intake | total_outcome | euthanasia_cases | total_death_cases | save_rate(total death) | save_rate(euthanasia) | |
---|---|---|---|---|---|---|---|
0 | 2013 | 4182.0 | 3770 | 430 | 462 | 88.952654 | 89.717838 |
1 | 2014 | 18654.0 | 18559 | 1844 | 2080 | 88.849576 | 90.114721 |
2 | 2015 | 18709.0 | 18485 | 1461 | 1684 | 90.998984 | 92.190924 |
3 | 2016 | 17673.0 | 17662 | 1161 | 1434 | 91.885928 | 93.430657 |
4 | 2017 | 17559.0 | 17643 | 1083 | 1327 | 92.442622 | 93.832223 |
5 | 2018 | 16975.0 | 16734 | 808 | 1036 | 93.896907 | 95.240059 |
6 | 2019 | 19726.0 | 19769 | 788 | 1127 | 94.286728 | 96.005272 |
7 | 2020 | 9585.0 | 9773 | 698 | 892 | 90.693792 | 92.717788 |
8 | 2021 | 12040.0 | 11962 | 597 | 789 | 93.446844 | 95.041528 |
9 | 2022 | 11891.0 | 11882 | 607 | 770 | 93.524514 | 94.895299 |
10 | 2023 | 10794.0 | 10575 | 490 | 693 | 93.579767 | 95.460441 |
no_kill_by_m = no_kill_rate(no_kill_research, "intake_m", "outcome_m")
month_order = ["January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"]
no_kill_by_m["time"] = pd.Categorical(no_kill_by_m["time"],
categories=month_order,
ordered=True)
no_kill_by_m = no_kill_by_m.sort_values("time").reset_index(drop=True)
no_kill_by_m
time | total_intake | total_outcome | euthanasia_cases | total_death_cases | save_rate(total death) | save_rate(euthanasia) | |
---|---|---|---|---|---|---|---|
0 | January | 10831 | 11418 | 555 | 660 | 93.906380 | 94.875819 |
1 | February | 9835 | 9974 | 679 | 776 | 92.109812 | 93.096085 |
2 | March | 11944 | 11685 | 1427 | 1692 | 85.833891 | 88.052579 |
3 | April | 12479 | 11213 | 929 | 1080 | 91.345460 | 92.555493 |
4 | May | 16165 | 13519 | 913 | 1140 | 92.947727 | 94.351995 |
5 | June | 15733 | 15093 | 1042 | 1332 | 91.533719 | 93.376978 |
6 | July | 14429 | 15330 | 820 | 1096 | 92.404186 | 94.317000 |
7 | August | 13990 | 14991 | 726 | 982 | 92.980701 | 94.810579 |
8 | September | 13727 | 13670 | 686 | 881 | 93.581992 | 95.002550 |
9 | October | 14931 | 14179 | 907 | 1110 | 92.565803 | 93.925390 |
10 | November | 12591 | 12971 | 700 | 846 | 93.280915 | 94.440473 |
11 | December | 11133 | 12771 | 583 | 699 | 93.721369 | 94.763316 |