расширение каждой строки в dataframe

голоса
1

Рассмотрим простой пример

data = pd.DataFrame({'mydate' : [pd.to_datetime('2016-06-06'),
                                 pd.to_datetime('2016-06-02')],
                     'value' : [1, 2]})

data.set_index('mydate', inplace = True)

data
Out[260]: 
            value
mydate           
2016-06-06      1
2016-06-02      2

Я хочу перебрать каждой строки, так что dataframe получает «увеличен» на пару дней (2 дня назад, через 2 дня после) вокруг каждого значения индекса (который является дата) для текущей строки.

Например, если рассматривать первую строку, я хочу сказать , панды , чтобы добавить еще 4 строки, соответствующие дни 2016-06-04, 2016-06-05, 2016-06-07и 2016-06-07. valueДля этих дополнительных строк может быть просто whathever в valueтечение этой строки (в данном случае: 1). Эта логика применяется каждую строку и окончательный dataframe является конкатенация всех этих увеличенных dataframes.

Я попытался следующие функции в apply(., axis = 1):

def expand_onerow(df, ndaysback = 2, nhdaysfwd = 2):

    new_index = pd.date_range(pd.to_datetime(df.name) - pd.Timedelta(days=ndaysback), 
                              pd.to_datetime(df.name) + pd.Timedelta(days=nhdaysfwd), 
                              freq='D')

    newdf = df.reindex(index=new_index, method='nearest')     #New df with expanded index
    return newdf

Но , к сожалению , я бег data.apply(lambda x: expand_onerow(x), axis = 1) дает:

  File pandas/_libs/tslib.pyx, line 1165, in pandas._libs.tslib._Timestamp.__richcmp__

TypeError: (Cannot compare type 'Timestamp' with type 'str', 'occurred at index 2016-06-06 00:00:00')

Другой подход, который я попробовал это следующее: я первый сбросить индекс,

data.reset_index(inplace = True)
data
Out[339]: 
      mydate  value
0 2016-06-06      1
1 2016-06-02      2

Затем я использую небольшую модификацию моей функции

def expand_onerow_alt(df, ndaysback = 2, nhdaysfwd = 2):

    new_index = pd.date_range(pd.to_datetime(df.mydate) - pd.Timedelta(days=ndaysback), 
                              pd.to_datetime(df.mydate) + pd.Timedelta(days=nhdaysfwd), 
                              freq='D')
    newdf = pd.Series(df).reindex(index = new_index).T  #New df with expanded index
    return newdf

который дает

data.apply(lambda x: expand_onerow_alt(x), axis = 1)
Out[338]: 
   2016-05-31  2016-06-01  2016-06-02  2016-06-03  2016-06-04  2016-06-05  2016-06-06  2016-06-07  2016-06-08
0         nan         nan         nan         nan         nan         nan         nan         nan         nan
1         nan         nan         nan         nan         nan         nan         nan         nan         nan

ближе, но еще не там ...

Я не понимаю, что здесь не так. Что мне не хватает? Я ищу наиболее Pandonic подход здесь.

Благодаря!

Задан 28/02/2018 в 16:59
источник пользователем
На других языках...                            


1 ответов

голоса
1

Я изменяю немного вашей функции

def expand_onerow(df, ndaysback = 2, nhdaysfwd = 2):

    new_index = pd.date_range(pd.to_datetime(df.index[0]) - pd.Timedelta(days=ndaysback),
                              pd.to_datetime(df.index[0]) + pd.Timedelta(days=nhdaysfwd),
                              freq='D')

    newdf = df.reindex(index=new_index, method='nearest')     #New df with expanded index
    return newdf

pd.concat([expand_onerow(data.loc[[x],:], ndaysback = 2, nhdaysfwd = 2) for x ,_ in data.iterrows()])


Out[455]: 
            value
2016-05-31      2
2016-06-01      2
2016-06-02      2
2016-06-03      2
2016-06-04      2
2016-06-04      1
2016-06-05      1
2016-06-06      1
2016-06-07      1
2016-06-08      1

Больше информации

В принципе, что одна линия равна

l=[]
for x ,_ in data.iterrows():

    l.append(expand_onerow(data.loc[[x],:], ndaysback = 2, nhdaysfwd = 2))# query out each row by using their index(x is the index for each row) and append then into a empty list


pd.concat(l)# concat the list to one df at the end 
Ответил 28/02/2018 в 17:17
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more