Почему функция r cpp работает медленно? - PullRequest
0 голосов
/ 29 января 2020

Я сделал простую функцию, которая устанавливает для столбца reversal_indicator значение «да», если значение в Reversal_Accounting_Transaction_ID присутствует в любом месте столбца Accounting_Transaction_ID (т.е. в других строках). Большинство записей в столбце Reversal_Accounting_Transaction_ID, вероятно, будут пустыми и поэтому должно быть «нет».

Фрейм данных создается из CSV-файла 6 ГБ (предположим, приблизительно 6 миллионов строк) и обрабатывается на кирпичах данных.

Я не совсем уверен, почему он принимает такое долгое время

Rcpp::cppFunction('
std::vector<std::string>
reversals(DataFrame frame)
{
  std::vector<std::string> Accounting_Transaction_ID = as<std::vector<std::string> >(frame["BELNR"]);
  std::vector<std::string> Reversal_Accounting_Transaction_ID = as<std::vector<std::string> >(frame["STBLG"]);
  std::vector<std::string> ReversalIndicator(Reversal_Accounting_Transaction_ID.size()) ;

  if (Reversal_Accounting_Transaction_ID.size() == 0) {
    return ReversalIndicator;
  }
  int dfSize = Reversal_Accounting_Transaction_ID.size();
  for (int i = 0; i < dfSize; ++i) {
    if (Reversal_Accounting_Transaction_ID[i] != "") {
      for (int j = 1; j < dfSize; ++j) {
        if(Accounting_Transaction_ID[j]== Reversal_Accounting_Transaction_ID[i]){
            ReversalIndicator[i]="Yes";
            break;
                                                                                }
         else if( (j== dfSize -1)  ){
                 ReversalIndicator[i]="No";
                                                                                                            }
                                      }
                                                    }
   else{
      ReversalIndicator[i]="No";
       }
                                  }
  return ReversalIndicator;
}

')```

```df$reversal=reversals(df)```

Ответы [ 2 ]

4 голосов
/ 30 января 2020

Вы пересекаете свой фрейм данных для каждой строки своего фрейма данных, т.е. у вас есть что-то вроде операций 6 х 6 м (O (N ^ 2)). Это может занять довольно много времени. Однако вы можете go из O (N ^ 2) в O (N) за счет некоторого объема памяти. Без примеров данных я не могу проверить это, поэтому я предоставляю только псевдокод:

create empty set data structure

for each row in df:
     Add Reversal_Accounting_Transaction_ID to set

for each row in df:
     if Accounting_Transaction_ID can be found in set
         ReversalIndicator = "Yes"
1 голос
/ 31 января 2020

Основано на ответе Ральфа

Не уверен, если мне нужно выделить набор размером в начале?

Rcpp::cppFunction('
std::vector<std::string> reversals(DataFrame frame)
{
  std::vector<std::string> Accounting_Transaction_ID = as<std::vector<std::string> >(frame["BELNR"]);
  std::vector<std::string> Reversal_Accounting_Transaction_ID = as<std::vector<std::string> >(frame["STBLG"]);
  std::vector<std::string> ReversalIndicator(Reversal_Accounting_Transaction_ID.size()) ;

  std::set<std::string> uniqueTransID;


  if (Reversal_Accounting_Transaction_ID.size() == 0) {
    return ReversalIndicator;
  }
  int dfSize = Reversal_Accounting_Transaction_ID.size();


 for (int i = 0; i < dfSize; ++i) {
    uniqueTransID.insert(Accounting_Transaction_ID[i]);
 }

  for (int i = 0; i < dfSize; ++i) {

      if (Reversal_Accounting_Transaction_ID[i] !=""){

             ReversalIndicator[i]="No";
             continue;
                                                         }
    if (uniqueTransID.find(Reversal_Accounting_Transaction_ID[i]) != uniqueTransID.end()) {

                 ReversalIndicator[i]="Yes";

                                      }

   else{
      ReversalIndicator[i]="No";

       }
                                  }
  return ReversalIndicator;
}


')```
...