Я ищу способ ускорить мой сценарий в pandas dataframe.
Чтобы понять ситуацию, я проиллюстрирую два набора данных, которые участвуют в сценарии.
Сначала у нас есть"entrydata", это список вещей, которые мы купили.который имеет столбец с именем «date», столбец с именем «id» и столбец с именем «value», как в таблице выше:
<table>
<tr>
<th>Date</th>
<th>Id</th>
<th>Value</th>
</tr>
<tr>
<td>01/01/2017</td>
<td>111</td>
<td>58.4</td>
</tr>
<tr>
<td>01/01/2017</td>
<td>222</td>
<td>120.7</td>
</tr>
<tr>
<td>02/18/2017</td>
<td>111</td>
<td>59.3</td>
</tr>
<tr>
<td>02/18/2017</td>
<td>222</td>
<td>130.8</td>
</tr>
<tr>
<td>04/13/2017</td>
<td>111</td>
<td>59.3</td>
</tr>
<tr>
<td>04/13/2017</td>
<td>222</td>
<td>130.8</td>
</tr>
</table>
Другие данные, которые у нас есть, это «outdata», то есть список вещей, которые мы продаем, у нас есть столбец с именем «date», столбец с именем «id»"и столбец с именем" значение ", как в таблице выше:
<table>
<tr>
<th>Date</th>
<th>Id</th>
<th>Value</th>
</tr>
<tr>
<td>01/03/2017</td>
<td>111</td>
<td>60</td>
</tr>
<tr>
<td>01/03/2017</td>
<td>111</td>
<td>60</td>
</tr>
<tr>
<td>01/03/2017</td>
<td>111</td>
<td>60</td>
</tr>
<tr>
<td>01/03/2017</td>
<td>222</td>
<td>122</td>
</tr>
<tr>
<td>01/03/2017</td>
<td>222</td>
<td>122</td>
</tr>
<tr>
<td>02/25/2017</td>
<td>222</td>
<td>122</td>
</tr>
<tr>
<td>02/25/2017</td>
<td>111</td>
<td>70</td>
</tr>
<tr>
<td>02/25/2017</td>
<td>222</td>
<td>135</td>
</tr>
</table>
С этими наборами данных я написал скрипт, который использовал цикл for, как показано выше:
for row in tqdm(zip(dbOut["Date"],dbOut["Id"],dbOut["Value"])):
dateOut = row[0]
idOut = row[1]
valueOut = row[2]
#get all entry rows that have idOut id
dbSample = dbEntry.loc[dbEntry["Id"] == idOut]
#now do the mean of the column Value
result = dbSample["Value"].mean()
#append to an array created before the loop
valuefinal.append(result)
#out of loop we put it in the outdata dataFrame in a new column
dbOut["FinalValue"] = valuefinal
По сути, это то, что делает скрипт,В кадрах входа и выхода есть больше столбцов, но с этим примером я думаю, что я возобновил происходящее.
Этот код отлично работает с точки зрения результата, но я хотел бы ускорить его.Сначала код был написан с использованием цикла iterrows.Ища способ ускориться, я увидел, что iterrows был плохим выбором.Так что я перешел на itertuples, а затем на функцию zip.
Все это работает с точки зрения результата, но время итераций не сильно изменилось.я говорю о 300 итерациях в секунду.
Чем я изменил часть кода, используя векторизацию, и в зависимости от входных данных я получил увеличение от 600 до 1200 итераций в секунду.
некоторую часть кода можно было векторизовать, а другую - нет!Часть, которая могла быть векторизована, была той, которая делает простое вычитание, используя два других столбца.
Часть, которая использовала уменьшенный кадр данных с определенным Id, который я не мог векторизовать, потому что это показывало следующую ошибку:
ValueError: Может сравнивать только идентично помеченные объекты Series
Код, который я пытался векторизовать, я просто удалил из цикла и внес необходимые изменения.Вот оригинальный код внутри цикла:
result = dbSample["Value"].mean
А вот код, который я пытался векторизовать, удаляя цикл:
dbOut["FinalValue"] = dbEntry.loc[dbEntry["Id"] == dbOut["Id"]]["Value"].mean()
Наконец, к вопросу.Могу ли я сделать этот вид векторизации с определенной частью кадра данных (entryData)?Любые предложения, чтобы сделать код работает быстрее?Как 3000iterations / секунда?
Заранее спасибо!