2017-08-18 57 views
6

Mam ramkę danych z nazwami kursów dla każdego roku. Muszę znaleźć czas w miesiącach, począwszy od roku 2016.Przyrost wypełnienia Pandy w tył o 12 miesięcy

from io import StringIO 

import pandas as pd 

u_cols = ['page_id','web_id'] 
audit_trail = StringIO(''' 
year_id | web_id 
2012|efg 
2013|abc 
2014| xyz 
2015| pqr 
2016| mnp 
''') 

df11 = pd.read_csv(audit_trail, sep="|", names = u_cols ) 

Jak dodać miesięcy w nowej kolumnie zaczynając od najwyższego (czyli dno jak bfill?)

Ostateczne dane ramki będą wyglądać tak ...

u_cols = ['page_id','web_id' , 'months'] 
audit_trail = StringIO(''' 
year_id | web_id | months 
2012|efg | 60 
2013|abc | 48 
2014| xyz | 36 
2015| pqr | 24 
2016| mnp | 12 
''') 

df12 = pd.read_csv(audit_trail, sep="|", names = u_cols ) 

Niektóre z odpowiedzi nie biorą pod uwagę, że może być wiele kursów. Aktualizacja danych przykładowych ...

from io import StringIO 

import pandas as pd 

u_cols = ['course_name','page_id','web_id'] 
audit_trail = StringIO(''' 
course_name| year_id | web_id 
a|2012|efg 
a|2013|abc 
a|2014| xyz 
a|2015| pqr 
a|2016| mnp 
b|2014| xyz 
b|2015| pqr 
b|2016| mnp 

''') 

df11 = pd.read_csv(audit_trail, sep="|", names = u_cols ) 

Odpowiedz

5
>>> df11.assign(months=df11.groupby('course_name').year_id.transform(
     lambda years: range(len(years) * 12, 0, -12))) 
    course_name year_id web_id months 
0   a  2012 efg  60 
1   a  2013 abc  48 
2   a  2014 xyz  36 
3   a  2015 pqr  24 
4   a  2016 mnp  12 
5   b  2014 xyz  36 
6   b  2015 pqr  24 
7   b  2016 mnp  12 
+0

Nice! Zapomniałem o 'transform' nie wymagającym indeksu. – piRSquared

4

Można użyć transform z arange:

df11['months'] = df11.groupby('course_name')['year_id'] \ 
        .transform(lambda x: np.arange(len(x)*12, 0, -12)) 
print (df11) 
    course_name year_id web_id months 
0   a  2012  efg  60 
1   a  2013  abc  48 
2   a  2014  xyz  36 
3   a  2015  pqr  24 
4   a  2016  mnp  12 
5   b  2014  xyz  36 
6   b  2015  pqr  24 
7   b  2016  mnp  12 
7
df11.assign(
    months=df11.groupby('course_name').apply(
     lambda x: pd.Series(np.repeat([12], len(x)).cumsum()[::-1]) 
    ).values 
) 

    course_name year_id web_id months 
0   a  2012 efg  60 
1   a  2013 abc  48 
2   a  2014 xyz  36 
3   a  2015 pqr  24 
4   a  2016 mnp  12 
5   b  2014 xyz  36 
6   b  2015 pqr  24 
7   b  2016 mnp  12 

Wszystko zgłosił @Alexander i @jezrael za przypomnienie nam o fajna cecha transform
Biorąc pod uwagę, że mogę zmienić moją odpowiedź na

df11.assign(months=df11.groupby('course_name').year_id.transform(
    lambda x: np.repeat([12], len(x)).cumsum()[::-1] 
)) 

    course_name year_id web_id months 
0   a  2012 efg  60 
1   a  2013 abc  48 
2   a  2014 xyz  36 
3   a  2015 pqr  24 
4   a  2016 mnp  12 
5   b  2014 xyz  36 
6   b  2015 pqr  24 
7   b  2016 mnp  12