Панды: динамическое смещение значений по столбцам - PullRequest
2 голосов
/ 28 мая 2019

У меня есть следующий df:

           sales2001   sales2002   sales2003  sales2004
   200012  19.12       0.98 
   200101  19.1        0.98        2.3
   200102  21          0.97        0.8
    ...
   200112  19.12       0.99        2.4
   200201              0.98        2.5
   200202              0.97        0.8        1.2

Я хотел бы сместить содержимое, чтобы выровнять его по временному интервалу, как показано ниже:

           sales+1y   sales+2y
   200012  19.12       0.98 
   200101  0.98        2.3       
   200102  0.97        0.8
    ...
   200112  0.99        2.4
   200201  0.98        2.5
   200202  0.8         1.2

в основном выравнивание прогнозируемых точек данных с фиксированным временным интервалом по индексу. Я попытался с помощью iterrows и динамически вызывать столбцы с учетом индекса, но не могу заставить его работать. ребята, у вас есть предложения?

Ответы [ 2 ]

2 голосов
/ 28 мая 2019

Используйте justify с DataFrame.dropna и axis=1 для удаления всех столбцов хотя бы с одним NaN:

df1 = (pd.DataFrame(justify(df.values, invalid_val=np.nan, side='right'), index=df.index)
          .dropna(axis=1))

При необходимости выберите последние столбцы по позиции:

df1 = pd.DataFrame(justify(df.values, invalid_val=np.nan, side='right')[:, -2:],index=df.index)

Или:

df1 = (pd.DataFrame(justify(df.values, invalid_val=np.nan, side='right'), index=df.index)
        .iloc[:, -2:])

df1.columns = [f'sales+{i+1}y' for i in range(len(df1.columns))]
print (df1)
        sales+1y  sales+2y
200012     19.12      0.98
200101      0.98      2.30
200102      0.97      0.80
200112      0.99      2.40
200201      0.98      2.50
200202      0.80      1.20
1 голос
/ 28 мая 2019

Другой вариант - использовать pd.wide_to_long и pivot:

# here I assume the index name is index
new_df = pd.wide_to_long(df.reset_index(), 'sales', i='index', j='sale_end').reset_index()

# if index is datetime, then use dt.year
new_df['periods'] = new_df['sale_end'] - new_df['index']//100

# pivot
new_df.dropna().pivot(index='index',columns='periods', values='sales')

выход:

periods -1      0       1       2
idx                 
200012  NaN     NaN     19.12   0.98
200101  NaN     19.10   0.98    2.30
200102  NaN     21.00   0.97    0.80
200112  NaN     19.12   0.99    2.40
200201  0.98    2.50    NaN     NaN
200202  0.97    0.80    1.20    NaN
...