Набор групп и набор фильтров

#python #python-3.x #pandas #dataframe #regression

#python #python-3.x #панды #фрейм данных #регрессия

Вопрос:

 df  fruit   year price  vol  signifiance
0   apple   2010  1      5 
1   apple   2011  2      4   
2   apple   2012  3      3   
3   apple   2013  3      3   
4   apple   2014  3      3   
5   apple   2015  3      3   important
...
47   banana  2010  1      4
  

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

например, для Apple, уменьшите цену на объем с 2010 по 2020 год.

Я пытался:

 df = df.groupby('significance')
Y = df['price']
X = df['vol']
model = sm.OLS(Y,X)
  

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

1. Для каждой группы всегда есть только один или ноль important fruit ?

2. В плоде может быть несколько «важных» лет, но они не перекрываются.

3. Являются ли годы последовательными для групп?

4. У некоторых фруктов разные годы начала, но это годовые данные для каждого фрукта

Ответ №1:

Я считаю, что вам нужно:

 import statsmodels.api as sm

g = df.groupby('fruit')
for group in g.groups.keys():
    df1 = g.get_group(group)
    #filter years with important rows
    years = df1.loc[df1['signifiance'].eq('important'), 'year']
    print (years)
    
    #for each year get get years between 5 previous and 5 next years
    for year in years:
        data = df1[df1['year'].between(year - 5, year   5)]
        print (data)

        #if returned data processing
        if not data.empty:
            X = data['vol'] 
            Y = data['price']
            model = sm.OLS(Y, X)
            results = model.fit()
            print (results.summary())
  

Редактировать:

 import statsmodels.api as sm


def f(df1):
    m1 = df1['signifiance'].eq('important')
    years = df1.loc[m1, 'year']
    print (years)
    
    #for each year get get years between 5 previous and 5 next years
    for year in years:
        mask = df1['year'].between(year - 5, year   5) amp; df1['vol'].notna() amp; df1['price'].notna()
        data = df1[mask] 
        # print (data)

        #if returned data processing
        if not data.empty:
            X = data['vol'] 
            Y = data['price']
            model = sm.OLS(Y, X)
            results = model.fit()
            # print (results.params)
            df1.loc[mask amp; m1, 'new'] = results.params.iat[0]
    return df1


df = df.groupby('fruit').apply(f)
print (df)
  

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

1. «exog содержит inf или nan». Разве data.empty не должен позаботиться об этом?

2. @asd — хммм, одна идея — изменить df1[df1['year'].between(year - 5, year 5)] на df1[df1['year'].between(year - 5, year 5) amp; df1['vol'].notna() amp; df1['price'].notna()]

3. Последнее, извините. Есть ли быстрый способ добавить коэффициент объема в качестве нового столбца рядом со столбцом signficance в df?

4. @asd — Как ты думаешь print (results.params) ?

5. Да results.params.vol , работал, работал, но в идеале хотел добавить его в исходный df