2013-08-27 2 views
2

сказать, что я DataFrame, который выглядит как этотРоллинг Reshape питона панды DataFrame

In [5]: dates = pd.date_range('20130101',periods=6) 

In [6]: dates 

<class 'pandas.tseries.index.DatetimeIndex'> 
[2013-01-01 00:00:00, ..., 2013-01-06 00:00:00] 
Length: 6, Freq: D, Timezone: None 

In [7]: df = pd.DataFrame(np.arange(0,24).reshape([6,4]),index=dates,columns=list('ABCD')) 

In [8]: df 

      A B C D 
2013-01-01 0 1 2 3 
2013-01-02 4 5 6 7 
2013-01-03 8 9 10 11 
2013-01-04 12 13 14 15 
2013-01-05 16 17 18 19 
2013-01-06 20 21 22 23 

Я хотел бы изменить df в нечто вроде этого

   A B C D A_1 B_1 C_1 D_1 A_2 B_2 C_2 D_2 
2013-01-03 8 9 10 11 4  5  6  7  0  1  2  3 
2013-01-04 12 13 14 15 8  9  10 11 4  5  6  7 
2013-01-05 16 17 18 19 12 13 14 15 8  9  10 11 
2013-01-06 20 21 22 23 16 17 18 19 12 13 14 15 

В принципе, расплющить предыдущие две строки и поместите его в дополнительные столбцы. Как я могу достичь этого эффективно? (также, могу ли я иметь уникальные заголовки столбцов тоже)

+0

это не обязательно, вы можете использовать roll_apply и друзей для выполнения вычислений * без * этого изменения формы взлома. –

ответ

0

Я бы дублировал дважды ваш исходный фрейм данных, а затем в первом экземпляре (df1) удалял первые две строки, во втором (df2) удалял первую строку. Затем слить столбцы из этих трех dataframe в таком порядке: df1.A .. df1.D df2.A .. df2.D df.A .. df.D

sorrt для нет реального кода, я пишу с телефона

2

Я действительно не знаю, почему вы это делаете, но вот как это можно сделать:

dates = pd.date_range('20130101',periods=6) 
columns = list('ABCD') 
df = pd.DataFrame(np.arange(0,24).reshape([6,4]),index=dates,columns=columns) 

# First setup some constants 
values = df.values.reshape(df.values.size,) 
step = 4 
size = step * len(columns) 
index = df.index[-step:] 

frame = pd.DataFrame(index=df.index[-step:]) 
for i, pos in enumerate(range(df.values.size-size, -1, -step)): 
    cols = columns if i == 0 else map(lambda x: '%s_%s' % (x, i), columns) 
    new_frame = pd.DataFrame(values[pos:pos+size].reshape((step, len(columns))), 
          index=index, columns=cols) 
    frame = pd.concat([frame, new_frame], axis=1) 
print(frame) 

что дает:

   A B C D A_1 B_1 C_1 D_1 A_2 B_2 C_2 D_2 
2013-01-03 8 9 10 11 4 5 6 7 0 1 2 3 
2013-01-04 12 13 14 15 8 9 10 11 4 5 6 7 
2013-01-05 16 17 18 19 12 13 14 15 8 9 10 11 
2013-01-06 20 21 22 23 16 17 18 19 12 13 14 15 
+0

разум пользователь может * подумать *, они хотят сделать это, чтобы написать свои собственные функции качения (а не использовать функции качания панды или 'roll_apply') ... __they * really * shouldn't__ (см. [Мой ответ] (http://stackoverflow.com/a/18462677/1240268)). –

+0

@ AndyHayden Если это так, я полностью согласен. Но он прямо заявил, что хочет «перевернуться» **: -/Вот почему я спросил его, почему. –

+0

Нет причин для этого. –

1

Панды имеет wealth of rolling computational functions что означает вы не должны делать это. Они будут значительно эффективнее (а также легче рассуждать).

Function    Description 
rolling_count   Number of non-null observations 
rolling_sum   Sum of values 
rolling_mean   Mean of values 
rolling_median   Arithmetic median of values 
rolling_min   Minimum 
rolling_max   Maximum 
rolling_std   Unbiased standard deviation 
rolling_var   Unbiased variance 
rolling_skew   Unbiased skewness (3rd moment) 
rolling_kurt   Unbiased kurtosis (4th moment) 
rolling_quantile  Sample quantile (value at %) 
rolling_apply   Generic apply 
rolling_cov   Unbiased covariance (binary) 
rolling_corr   Correlation (binary) 
rolling_corr_pairwise Pairwise correlation of DataFrame columns 
rolling_window   Moving window function 

Если ваш заключительный план игры включает в себя выполнение этих ... просто используйте их. Если это что-то еще, подумайте о том, чтобы написать его как общий переход.

В качестве примера, вот rolling_mean с тем же окном, который вы использовали:
то расчет производится по каждой строке и предыдущих два ряда.

In [11]: df = pd.DataFrame(np.random.randn(24).reshape([6,4]), 
          index=dates,columns=list('ABCD')) 

In [12]: df 
Out[12]: 
        A   B   C   D 
2013-01-01 0.225416 -1.014222 0.724756 -0.594679 
2013-01-02 1.629553 -1.100808 1.279953 -0.058152 
2013-01-03 -0.633830 0.019230 -0.477937 -0.852657 
2013-01-04 -0.601511 0.704212 -1.535412 -1.044537 
2013-01-05 -0.587404 -1.124893 0.834233 0.117244 
2013-01-06 -0.067674 -0.745053 0.589823 -1.007093 

In [13]: pd.rolling_mean(df, 3) 
Out[13]: 
        A   B   C   D 
2013-01-01  NaN  NaN  NaN  NaN 
2013-01-02  NaN  NaN  NaN  NaN 
2013-01-03 0.407046 -0.698600 0.508924 -0.501829 
2013-01-04 0.131404 -0.125788 -0.244465 -0.651782 
2013-01-05 -0.607582 -0.133817 -0.393039 -0.593317 
2013-01-06 -0.418863 -0.388578 -0.037119 -0.644795 

Примечание: Вы также можете установить частота быть DateOffset (например дни, минуты, часы и т.д.), что было бы труднее сделать с перекроить, и это дает вам большую гибкость.

See the docs для получения дополнительных примеров и способов написания общих применений.

Смежные вопросы