Нахождение 3-летнего повышения в индексе цен на жилье государством и округом - PullRequest
0 голосов
/ 30 января 2020

У меня есть набор данных, который выглядит следующим образом:

enter image description here

Я хочу найти трехлетнее повышение в hpi. Обратите внимание, что hpi находится на уровне тракта, а годы варьируются от 2012 до 2018 года.

Набор данных содержит все штаты и округа и намного больше, чем тот, который я только что продемонстрировал. Я думал об использовании некоторого типа группы по лямбда-функции, такой как эта, когда я хотел найти медиану hpi на основе года и штата

medians = (all_data.groupby(['Year', 'state', 'County_name'])['hpi']
             .transform(lambda x: x.median() if x.notnull().any() else np.nan)
          )
all_data['hpi'] = all_data['hpi'].fillna(medians)

Но я не смог адаптировать приведенный выше код для этого цель. Любые предложения приветствуются.

Ответы [ 2 ]

1 голос
/ 30 января 2020

Вот минимальный работающий пример:

import pandas as pd

# create data
data = {"Year": [2010, 2011, 2012, 2013, 2014]*2,
        "State": ["Bama", "Bama", "Bama", "Bama", "Bama",
                  "NY", "NY", "NY", "NY", "NY"],
        "hpi": [100, 105, 110, 115, 120]*2}
data = pd.DataFrame.from_dict(data)

# Create column with 3y shifted hpi
data["hpi_3y"] = data.groupby(["State"])["hpi"].shift(3)
# compute your appreciation value from the columns
data["3y_appreciation"] = 100 + ((data["hpi"] / data["hpi_3y"] - 1) * 100)
data

По сути, вы группируете по всем соответствующим столбцам (не включая год). Затем вы сдвигаете свои значения в столбце hpi 3 строки = 3 года. После этого у вас есть соответствующие hpi и hpi_3y в одной строке для каждого наблюдения, и вы можете просто вычислить.

Вывод:

|   Year | State   |   hpi |   hpi_3y |   3y_appreciation |
|-------:|:--------|------:|---------:|------------------:|
|   2010 | Bama    |   100 |      nan |           nan     |
|   2011 | Bama    |   105 |      nan |           nan     |
|   2012 | Bama    |   110 |      nan |           nan     |
|   2013 | Bama    |   115 |      100 |           115     |
|   2014 | Bama    |   120 |      105 |           114.286 |
|   2010 | NY      |   100 |      nan |           nan     |
|   2011 | NY      |   105 |      nan |           nan     |
|   2012 | NY      |   110 |      nan |           nan     |
|   2013 | NY      |   115 |      100 |           115     |
|   2014 | NY      |   120 |      105 |           114.286 |
1 голос
/ 30 января 2020

Я добавил дополнительный округ к вашим данным и составил вымышленный индекс для HPI для округа Барбур:

state = ["Alabama"] * 12
county = ["Baldin County"] * 6 + ["Barbour County"] * 6
year = [x for y in range(2) for x in range(2012, 2018)]
hpi = [125, 130, 127.5, 142, 160, 139, 98, 108, 102, 115, 118, 114]
data = {"Year": year, "State": state, "County": county, "HPI": hpi}

df = pd.DataFrame(data)

# Sorting is necessary.
df = df.sort_values(['State', 'County', 'Year'])
print(df)

    Year    State          County    HPI
0   2012  Alabama   Baldin County  125.0
1   2013  Alabama   Baldin County  130.0
2   2014  Alabama   Baldin County  127.5
3   2015  Alabama   Baldin County  142.0
4   2016  Alabama   Baldin County  160.0
5   2017  Alabama   Baldin County  139.0
6   2012  Alabama  Barbour County   98.0
7   2013  Alabama  Barbour County  108.0
8   2014  Alabama  Barbour County  102.0
9   2015  Alabama  Barbour County  115.0
10  2016  Alabama  Barbour County  118.0
11  2017  Alabama  Barbour County  114.0

Исходя из этой базы, мы смещаем «HPI» и делим, чтобы получить результаты данных, которые вы ищем.

df["3 year appreciation"] = df.HPI / df['HPI'].shift(3)
print(df)

    Year    State          County    HPI  3 year appreciation
0   2012  Alabama   Baldin County  125.0                  NaN
1   2013  Alabama   Baldin County  130.0                  NaN
2   2014  Alabama   Baldin County  127.5                  NaN
3   2015  Alabama   Baldin County  142.0             1.136000
4   2016  Alabama   Baldin County  160.0             1.230769
5   2017  Alabama   Baldin County  139.0             1.090196
6   2012  Alabama  Barbour County   98.0             0.690141
7   2013  Alabama  Barbour County  108.0             0.675000
8   2014  Alabama  Barbour County  102.0             0.733813
9   2015  Alabama  Barbour County  115.0             1.173469
10  2016  Alabama  Barbour County  118.0             1.092593
11  2017  Alabama  Barbour County  114.0             1.117647

Однако теперь у вас есть NaN в начале и неверные значения для первых трех лет каждого округа. Чтобы исправить это, мы группируем штат / округ, затем извлекаем первые три года для каждой группы, используя head (3), затем получаем значения индекса, затем фильтруем и устанавливаем в ноль.

df.loc[df.groupby(["State", "County"]).head(3).index, "3 year appreciation"] = 0
print(df)

    Year    State          County    HPI  3 year appreciation
0   2012  Alabama   Baldin County  125.0             0.000000
1   2013  Alabama   Baldin County  130.0             0.000000
2   2014  Alabama   Baldin County  127.5             0.000000
3   2015  Alabama   Baldin County  142.0             1.136000
4   2016  Alabama   Baldin County  160.0             1.230769
5   2017  Alabama   Baldin County  139.0             1.090196
6   2012  Alabama  Barbour County   98.0             0.000000
7   2013  Alabama  Barbour County  108.0             0.000000
8   2014  Alabama  Barbour County  102.0             0.000000
9   2015  Alabama  Barbour County  115.0             1.173469
10  2016  Alabama  Barbour County  118.0             1.092593
11  2017  Alabama  Barbour County  114.0             1.117647

Общий код :

import pandas as pd

state = ["Alabama"] * 12
county = ["Baldin County"] * 6 + ["Barbour County"] * 6
year = [x for y in range(2) for x in range(2012, 2018)]
hpi = [125, 130, 127.5, 142, 160, 139, 98, 108, 102, 115, 118, 114]
data = {"Year": year, "State": state, "County": county, "HPI": hpi}

df = pd.DataFrame(data)
df = df.sort_values(['State', 'County', 'Year'])

df["3 year appreciation"] = df.HPI / df['HPI'].shift(3)

df.loc[df.groupby(["State", "County"]).head(3).index, "3 year appreciation"] = 0
...