Как выполнить кумулятивное разделение на уровне groupby [0,1] в фрейме данных pandas на основе условий?

#python #pandas #dataframe #function #numpy

Вопрос:

У меня есть фрейм данных, в котором я хочу добавить строку, добавить некоторые группы дополнительные условия. Ищу цикл или другое решение, которое может сработать.

или если это проще…

first melt df, а затем добавьте new ratio % col затем unmelt .

Поскольку расчеты настраиваются индивидуально, я думаю for loop , что смогу найти решение с помощью groupby или без него.

—Строка 6,7,8-это мое требование.—

0-14 = child and unemployed

14-50 = young and working

50 = old and unemployed

# ref line 6,7,8 = showing which rows to ( ) and (/)

В настоящее время я хочу поставить 3 условия в выходной строке 6,7,8:

 d = { 'year': [2019,2019,2019,2020,2020,2020], 
      'age group': ['(0-14)','(14-50)','(50 )','(0-14)','(14-50)','(50 )'], 
      'con': ['UK','UK','UK','US','US','US'],
      'population': [10,20,300,400,1000,2000]}
df = pd.DataFrame(data=d)
df2 = df.copy()
df

    year    age group   con population
0   2019    (0-14)  UK  10
1   2019    (14-50) UK  20
2   2019    (50 )   UK  300
3   2020    (0-14)  US  400
4   2020    (14-50) US  1000
5   2020    (50 )   US  2000

 

требуемая производительность:

     year    age group           con                   population
0   2019    (0-14)              UK                      10.0
1   2019    (14-50)             UK                      20.0
2   2019    (50 )               UK                      300.0
3   2020    (0-14)              US                      400.0
4   2020    (14-50)             US                      1000.0
5   2020    (50 )               US                      2000.0
6   2019    young vs child      UK-young vs child       2.0   # 20/10
7   2019    old vs young        UK-old vs young          15.0   #300/20
8   2019  unemployed vs working UK-unemployed vs working. 15.5  #300 10 20
 

Испытания сейчас:

 df2 = df.copy()
criteria = [df2['con'].str.contains('0-14'),
            df2['con'].str.contains('14-50'),
            df2['con'].str.contains('50 ')]
#conditions should be according to requirements

values = ['young vs child','old vs young', 'unemployed vs working']

df2['con'] = df2['con'] '_' np.select(criteria, values, 0)
df2['age group'] = df2['age group'] '_' np.select(criteria, values, 0)

df.groupby(['year','age group','con']).sum().groupby(level=[0,1]).cumdiv()

pd.concat([df,df2])

#----errors. cumdiv() not found and missing conditions criteria-------
 

также пробовал:

 df['population'].div(df.groupby('con')['population'].shift(1))

#but looking for customisations into this 
#so it can first sum rows and then divide 
#according to unemployed condition-- row 8 reference. 

 

БЛИЖАЙШАЯ ТРОПА

 n_df_2 = df.copy()
con_list = [x for x in df.con]
year_list = [x for x in df.year]
age_list = [x for x in df['age group']]
new_list = ['young vs child','old vs young', 'unemployed vs working']

for country in con_list:
  

      bev_child =  n_df_2[(n_df_2['con'].str.contains(country)) amp; (n_df_2['age group'].str.contains(age_list[0]))]
      bev_work =  n_df_2[(n_df_2['con'].str.contains(country)) amp; (n_df_2['age group'].str.contains(age_list[1]))]
      bev_old =  n_df_2[(n_df_2['con'].str.contains(country)) amp; (n_df_2['age group'].str.contains(age_list[2]))]


      bev_child.loc[:,'population'] = bev_work.loc[:,'population'].max() / bev_child.loc[:,'population'].max() 
      bev_child.loc[:,'con'] = country  '-' new_list[0]
      bev_child.loc[:,'age group'] = new_list[0]
      s = n_df_2.append(bev_child, ignore_index=True)


      bev_child.loc[:,'population'] = bev_child.loc[:,'population'].max()   bev_old.loc[:,'population'].max()/ bev_work.loc[:,'population'].max() 
      bev_child.loc[:,'con'] = country  '-'  new_list[2]
      bev_child.loc[:,'age group'] = new_list[2]

      s = s.append(bev_child, ignore_index=True)

      bev_child.loc[:,'population'] = bev_old.loc[:,'population'].max() / bev_work.loc[:,'population'].max() 
      bev_child.loc[:,'con'] = country  '-'  new_list[1]
      bev_child.loc[:,'age group'] = new_list[1]

      s = s.append(bev_child, ignore_index=True)
s

year    age group                  con                   population
0   2019    (0-14)                 UK                             10.0
1   2019    (14-50)                UK                             20.0
2   2019    (50 )                  UK                            300.0
3   2020    (0-14)                 US                            400.0
4   2020    (14-50)                US                           1000.0
5   2020    (50 )                  US                           2000.0
6   2020    young vs child         US-young vs child               2.5
7   2020    unemployed vs working  US-unemployed vs working        4.5
8   2020    old vs young           US-old vs young                 2.0
 

тоже
ПОЖАЛУЙСТА, найдите самый простой способ решить эту проблему… Пожалуйста…

Комментарии:

1. Я не совсем понимаю ваш вопрос, вы хотите сгруппироваться по 1-й и 2-й колонкам? откуда берутся эти строки 6,7,8 output required ?

2. Да, строка 6,7,8-это мое требование @haneulkim. Что я показываю, как это будет выглядеть.

3. Я не понимаю, что такое новые ценности населения. Кажется, что вы делите на предыдущую строку, но тогда строка 8 для меня не имеет смысла. Если вы хотите разделить на предыдущее значение после группировки по «con», вам нужно следующее: df[‘население’].div(df.groupby(‘con’)[‘население’]. сдвиг(1))

4. Я думаю, что groupby не будет работать в этой ситуации, потому что это индивидуальный расчет разделения, может быть, над ним может работать любая функция. @цини