2017-02-20 43 views
0

У меня есть кадр данных и серия тарифов. Мой расчет очень прост:строка (n-1) * rate + row (n) в кадре данных pandas

NEW_ROW (п) = NEW_ROW (п-1) * ставка + old_row (п)

У меня есть 20 столбцов в моей dataframe. ставка - это серия из 20 (по 1 для каждого столбца). Я написал код с использованием циклов, которые занимают почти 9 секунд для запуска. Я считаю, что это не идеальный способ сделать это упражнение. Я бы хотел найти питонический способ сделать это.

data = pd.read_csv('data.csv') 
ret_rate = pd.read_csv('Retention_Rate.csv') 

ret_dat = data.copy() 
for i in range(4, ret_dat.shape[1]): 
    for j in range(1, ret_dat.shape[0]): 
     if (ret_dat['MARKET_ID'][j] == ret_dat['MARKET_ID'][j-1]): 
     ret_dat.iloc[j, i] = ret_dat.iloc[j, i] + ret_rate.iloc[i-4,0]*ret_dat.iloc[j-1, i] 

ret_dat.to_csv('adstock_data_v3.csv') 

Я поместил данные in a Google sheet.

ответ

0

Наконец нашел решение. На данный момент это самое оптимальное решение, которое я мог найти. Использование обработки сигналов от scipy.signal.lfilter. Здесь идет решение:

for media_var in self.config.media_vars: adstocked_vals = lfilter([1], [1, -ret_rate[media_var]], data[media_var])

Спасибо всем, кто дал разные ответы. Это помогло мне так или иначе. Благодаря решению Уоррена Уокессера на другую тему here

0
  1. Просто используйте кусочек data, который представляет интерес

  2. Серия ret_rate для демонстрации целей диапазона с длиной, равной количеству столбцов data

  3. Вы умножать data с ret_rate по столбцам (axis=1) и shift этот DataFrame по одному и добавить начальный DataFrame

в коде:

data = pd.read_csv("data_so.csv").iloc[:,4:] 
ret_rate = pd.Series(range(df.shape[1]), index=df.columns) 
data.multiply(ret_rate, 1).shift() + data 

Так что все расчеты ИСТ только одна линия панд.

Для multiply() важно, чтобы индекс ret_rate был равен именам столбцов data.

+0

ret_rate имеет значения в csv. сталкиваясь с трудностями в преобразовании этого в ряд с индексом, который является data.columns. любая помощь с этим пожалуйста ... 'ret_rate_s = pd.Series (ret_rate.ix [:, 0], index = data.columns)' дает мне все NaN – Nil

+0

Чтобы прочитать csv как серию, вы должны использовать панды function ['read_csv'] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html). Либо csv имеет только один столбец, либо вы определяете столбец для использования с параметром 'usecols'. В любом случае, если вы задали 'squeeze = True', функция' read_csv' возвращает серию вместо DataFrame. И после прочтения csv вы можете установить 'ret_rate.index = data.columns' – elcombato

+0

Это сработало! @elcombato. Я мог бы создать серию, но потом, только чтобы понять, что df.multiply не может обрабатывать тип float. Разрешены только Intergers! облом! – Nil

0

Я не уверен, если это то, что вы пытаетесь достичь, - но это проще и прямой перевод формулы и дал

data = pd.read_csv('data.csv') 
ret_rate = pd.read_csv('Retention_Rate.csv',usecols=['rate']) 
# since you require only the 5th column onwards 
ret_data = data.ix[:,4:] 

# you can apply broad operations over rows instead of individual cells now 
for i in range(1,len(ret_data)): 
    ret_data.iloc[i] = ret_data.iloc[i-1].multiply(ret_rate.rate.iloc[i-1]) + ret_dat.iloc[i] 

ret_data.to_csv('your_filename.csv',sep=',') 
+0

Возможно, я делаю глупую ошибку ... но это только дает мне первую строку вывода. отдых - все NaN. – Nil