Как обновить столбец, используя другой столбец в пандах - PullRequest
0 голосов
/ 26 апреля 2018

Я пытаюсь создать информационный фрейм, который отслеживает количество государственных школ, открытых в период с 2010 по 2016 годы.

StatusType  County  2010 ...2016    OpenYear    ClosedYear
1   Closed  Alameda 0        0        2005        2015.0
2   Active  Alameda 0        0        2006         NaN
3   Closed  Alameda 0        0        2008        2015.0
4   Active  Alameda 0        0        2011         NaN
5   Active  Alameda 0        0        2011         NaN
6   Active  Alameda 0        0        2012         NaN
7   Closed  Alameda 0        0        1980        1989.0
8   Active  Alameda 0        0        1980         NaN
9   Active  Alameda 0        0        1980         NaN

Я хочу обновить столбцы 2010-2016, чтобы отслеживать количество школ, открытых в год. Например, первая школа в фрейме данных открывается в 2005 году и закрывается в 2015 году. Итератор должен проверить столбец «ClosedYear» и добавить 1 ко всем значениям строк столбцов <2015 (2010,2011 ..., 2014). Если в столбце «ClosedYear» указано «NaN», то, начиная с года в столбце «OpenYear», добавьте 1 к значениям строк всех столбцов> = «OpenYear» (например, школа № 4, столбцы [2011,2012 .. ., 2016] +1 & колонка [2010] без изменений)

Я думал об использовании «apply» для применения функции к фрейму данных. Но это может быть не самый эффективный способ решения проблемы. Нужна помощь в выяснении, как сделать эту работу! Спасибо!

Дополнительный шаг: После окончания подсчета я хочу сгруппировать столбцы года по округам. Я склоняюсь к использованию функции «groupby» w / sum для суммирования количества открытых школ в округе за год. Если бы кто-то мог добавить это с ответом на вопрос выше, было бы очень полезно.

Ожидаемый результат:

StatusType       County 2010 ...2016    OpenYear    ClosedYear
    1   Closed  Alameda 1        0        2005        2015.0
    2   Active  Alameda 1        1        2006         NaN
    3   Closed  Alameda 1        0        2008        2015.0
    4   Active  Alameda 0        1        2011         NaN
    5   Active  Alameda 0        1        2011         NaN
    6   Active  Alameda 0        1        2012         NaN
    7   Closed  Alameda 0        0        1980        1989.0
    8   Active  Alameda 1        1        1980         NaN
    9   Active  Alameda 1        1        1980         NaN

Ответы [ 2 ]

0 голосов
/ 26 апреля 2018

Если в действительности нет необходимости создавать эти промежуточные столбцы, вы можете получить счет непосредственно с помощью groupby и .size В зависимости от того, хотите ли вы включить год закрытия, измените неравенства с <= на <. Если вы хотите сгруппировать их по округам, вы можете сделать это на том же этапе.

Вот начало df

  StatusType   County  OpenYear  ClosedYear
1     Closed  Alameda      2005      2015.0
2     Active  Alameda      2006         NaN
3     Closed  Alameda      2008      2015.0
4     Active  Alameda      2011         NaN
5     Active  Alameda      2011         NaN
6     Active  Alameda      2012         NaN
7     Closed  Alameda      1980      1989.0
8     Active  Alameda      1980         NaN
9     Active  Alameda      1980         NaN

import pandas as pd
year_list = [2010, 2011, 2012, 2013, 2014, 2015, 2016]
df_list = []

for year in year_list:
    group = ((df.ClosedYear.isnull()) | (df.ClosedYear >= year)) & (df.OpenYear <= year)
    n_schools = df.groupby([group, df.County]).size()[True]
    df_list.append(pd.DataFrame({'n_schools':n_schools, 'year': year}))

ndf = pd.concat(df_list)
#         n_schools  year
#County                  
#Alameda          5  2010
#Alameda          7  2011
#Alameda          8  2012
#Alameda          8  2013
#Alameda          8  2014
#Alameda          8  2015
#Alameda          6  2016
0 голосов
/ 26 апреля 2018

Я чувствую, что должен быть способ сделать это без использования for loop, но я не могу думать об этом, вот мое решение:

# Read Example data
from io import StringIO # This only works python 3+
df = pd.read_fwf(StringIO(
"""StatusType  County    OpenYear    ClosedYear
Closed      Alameda   2005        2015.0
Active      Alameda   2006         NaN
Closed      Alameda   2008        2015.0
Active      Alameda   2011         NaN
Active      Alameda   2011         NaN
Active      Alameda   2012         NaN
Closed      Alameda   1980        1989.0
Active      Alameda   1980         NaN
Active      Alameda   1980         NaN"""))

# For each year
for year in range(2010, 2016+1):
    # Create a column of 0s
    df[str(year)] = 0
    # Where the year is between OpenYear and ClosedYear (or closed year is NaN) set it to 1
    df.loc[(df['OpenYear'] <= year) & (pd.isna(df['ClosedYear']) | (df['ClosedYear'] >= year)), str(year)] = int(1)

print(df.to_string)

Выход:

  StatusType   County  OpenYear  ClosedYear  2010  2011  2012  2013  2014  2015  2016
0     Closed  Alameda      2005      2015.0     1     1     1     1     1     1     0
1     Active  Alameda      2006         NaN     1     1     1     1     1     1     1
2     Closed  Alameda      2008      2015.0     1     1     1     1     1     1     0
3     Active  Alameda      2011         NaN     0     1     1     1     1     1     1
4     Active  Alameda      2011         NaN     0     1     1     1     1     1     1
5     Active  Alameda      2012         NaN     0     0     1     1     1     1     1
6     Closed  Alameda      1980      1989.0     0     0     0     0     0     0     0
7     Active  Alameda      1980         NaN     1     1     1     1     1     1     1
8     Active  Alameda      1980         NaN     1     1     1     1     1     1     1

(PS: я не совсем уверен, что вы пытались сделать с groupby)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...