2015-03-28 2 views
2

Я думаю, что это лучше всего иллюстрируется примерами. Допустим, у нас есть DataFrame, как например:Pandas, заполнение между датами со средним изменением между предыдущими рядами

    295340  299616 
2014-11-02 304.904110 157.123288 
2014-12-02 597.303413 305.488493 
2015-01-02 896.310372 454.614630 
2015-02-02 1192.379580 599.588466 
2015-02-04 1211.285484   NaN 
2015-03-02   NaN 726.622932 

Теперь, скажем, я хочу, чтобы индексировать это, как например:

rng = pd.date_range(df.index[0], df.index[-1]) 

df.reindex(rng) 
       295340  299616 
2014-11-02 304.904110 157.123288 
2014-11-03   NaN   NaN 
2014-11-04   NaN   NaN 
2014-11-05   NaN   NaN 
... 

2014-11-29   NaN   NaN 
2014-11-30   NaN   NaN 
2014-12-01   NaN   NaN 
2014-12-02 597.303413 305.488493 

Теперь, если мы посмотрим на 295340, мы видим, что разница между их значений (597,30-304.90) = 292,39.

Количество дней между этими двумя значениями равно 31. Таким образом, средний прирост составляет 9,43 в день.

Так что я хотел бы что-то вроде такого:

    295340  299616 
2014-11-02 304.904110 157.123288 
2014-11-03 314.336345   NaN 
2014-11-04 323.768581   NaN 
2014-11-05 333.200816   NaN 

Как я подсчитал, что было:

304.904110 + (((597.303413-304.904110)/31) * N) 

Где N 1 для первой строки, так как строки 1, 2 после того, и т. д.

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

Любые идеи для чего-то максимально эффективного? Я знаю способы сделать это, но ничего не кажется эффективным, и кажется, что должен быть какой-то тип fillna() или что-то, что работает для этой проблемы, связанной с финансами.

ПРИМЕЧАНИЕ. Столбцы не будут располагаться на одинаковом расстоянии. Каждый из них может иметь номера в любом диапазоне дат, поэтому я не могу просто предположить, что следующее число для каждого столбца будет на дату X.

+0

Для начала ознакомьтесь с '' 'resample()' '' – JohnE

ответ

2

Вы можете использовать DataFrame.interpolate с методом "time" после resample. (Это не даст довольно номера вы дали, потому что есть только 30 дней между 2 ноября и 2 декабря, а не 31):

>>> dnew = df.resample("1d").interpolate("time") 
>>> dnew.head(100) 
       295340  299616 
2014-11-02 304.904110 157.123288 
2014-11-03 314.650753 162.068795 
[...] 
2014-11-28 558.316839 285.706466 
2014-11-29 568.063483 290.651972 
2014-11-30 577.810126 295.597479 
2014-12-01 587.556770 300.542986 
2014-12-02 597.303413 305.488493 
2014-12-03 606.948799 310.299014 
[...] 
2014-12-30 867.374215 440.183068 
2014-12-31 877.019600 444.993589 
2015-01-01 886.664986 449.804109 
2015-01-02 896.310372 454.614630 
[...] 
2015-02-01 1182.828960 594.911891 
2015-02-02 1192.379580 599.588466 
[...] 

Недостатком здесь является то, что он будет экстраполировать с использованием последнего значения в конец:

[...] 
2015-01-31 1173.278341 590.235315 
2015-02-01 1182.828960 594.911891 
2015-02-02 1192.379580 599.588466 
2015-02-03 1201.832532 604.125411 
2015-02-04 1211.285484 608.662356 
2015-02-05 1211.285484 613.199302 
2015-02-06 1211.285484 617.736247 
[...] 

Таким образом, вам придется решить, как вы хотите справиться с этим.

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