Функция преобразования Pandas для выполнения пользовательских манипуляций со строками

#python #pandas #numpy

#python #pandas #numpy

Вопрос:

введите описание изображения здесьМы хотим создать столбец во фрейме данных под названием feature col, который представляет собой диапазон текущего значения и предыдущих 2 значений, разность max и min, как показано на рисунке. Как мы можем вычислить это в pandas?

В наборе данных есть несколько идентификаторов [![введите описание изображения здесь][2]][2]

 ID  Year    percentage
123 2009    0   
123 2010    -27 
123 2011    0
123 2012    -50
123 2013    3
123 2014    -3
123 2015    0
123 2016    -28
123 2017    -5  

Ответ №1:

Используйте Series.rolling с помощью метода numpy np.ptp , но сначала, если необходимо, удалите % и преобразуйте значения в числа:

 df['feature_col'] = df['percentage'].str.strip('%').astype(int).rolling(3).apply(np.ptp)
print (df)
    ID  Year percentage  feature_col
0  123  2009         0%          NaN
1  123  2010       -27%          NaN
2  123  2011         0%         27.0
3  123  2012       -50%         50.0
4  123  2013         3%         53.0
5  123  2014        -3%         53.0
6  123  2015         0%          6.0
7  123  2016       -28%         28.0
8  123  2017        -5%         28.0
  

Если вывод необходим с помощью % , то возможно использование:

 df['feature_col'] = (df['percentage'].str.strip('%')
                                     .astype(int)
                                     .rolling(3)
                                     .apply(np.ptp)
                                     .mask(lambda x: x.notna(), lambda x: x.astype('Int64').astype(str).add('%'))
                                     )
print (df)
    ID  Year percentage feature_col
0  123  2009         0%         NaN
1  123  2010       -27%         NaN
2  123  2011         0%         27%
3  123  2012       -50%         50%
4  123  2013         3%         53%
5  123  2014        -3%         53%
6  123  2015         0%          6%
7  123  2016       -28%         28%
8  123  2017        -5%         28%
  

РЕДАКТИРОВАТЬ: Если требуется обработка по группам по ID :

 print (df)
    ID  Year percentage
0  123  2009         0%
1  123  2010       -27%
2  123  2011         0%
3  123  2012       -50%
4  123  2013         3%
5  124  2014        -3%
6  124  2015         0%
7  124  2016       -28%
8  124  2017        -5%


df['feature_col'] = (df['percentage'].str.strip('%')
                                     .astype(int)
                                     .groupby(df['ID'])
                                     .rolling(3)
                                     .apply(np.ptp)
                                     .reset_index(level=0, drop=True))
print (df)
    ID  Year percentage  feature_col
0  123  2009         0%          NaN
1  123  2010       -27%          NaN
2  123  2011         0%         27.0
3  123  2012       -50%         50.0
4  123  2013         3%         53.0
5  124  2014        -3%          NaN
6  124  2015         0%          NaN
7  124  2016       -28%         28.0
8  124  2017        -5%         28.0
  

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

1. Я сделал это, чтобы рассмотреть возможность изменения идентификаторов df['feature_col'] = np.where(df.ID == df.ID.shift(1), df['percentage'].rolling(3).apply(np.ptp) , 0)