Python: уменьшить время цикла for - PullRequest
2 голосов
/ 21 мая 2019

Я хочу рассчитать APRU для нескольких стран.

country_list = ['us','gb','ca','id']

count = {}
for i in country_list:
    count[i] = df_day_country[df_day_country.isin([i])]
    count[i+'_reverse'] = count[i].iloc[::-1]
    for j in range(1,len(count[i+'_reverse'])): 
        count[i+'_reverse']['count'].iloc[j] = count[i+'_reverse']['count'][j-1:j+1].sum()
    for k in range(1,len(count[i])): 
        count[i][revenue_sum].iloc[k] = count[i][revenue_sum][k-1:k+1].sum()

    count[i]['APRU'] = count[i][revenue_sum] / count[i]['count'][0]/100

После этого я создам 4 кадра данных: df_us, df_gb, df_ca, df_id, которые показывают APRU каждой страны.

Но размер набора данных велик.Время работы очень медленно после того, как список стран увеличится.Так есть ли способ уменьшить время работы?

Ответы [ 2 ]

0 голосов
/ 21 мая 2019

IIUC, из вашего кода и имен переменных похоже, что вы пытаетесь вычислить среднее значение:

# toy data set:
country_list = ['us','gb']

np.random.seed(1)
datalen=10
df_day_country = pd.DataFrame({'country': np.random.choice(country_list, datalen),
                               'count': np.random.randint(0,100, datalen),
                               'revenue_sum': np.random.uniform(0,100,datalen)})


df_day_country['APRU'] =  (df_day_country.groupby('country',group_keys=False)
                            .apply(lambda x: x['revenue_sum']/x['count'].sum())
                          )

Выход:

+----------+--------+--------------+------------+----------+
| country  | count  | revenue_sum  |    APRU    |          |
+----------+--------+--------------+------------+----------+
|       0  | gb     |          16  | 20.445225  | 0.150333 |
|       1  | gb     |           1  | 87.811744  | 0.645675 |
|       2  | us     |          76  | 2.738759   | 0.011856 |
|       3  | us     |          71  | 67.046751  | 0.290246 |
|       4  | gb     |           6  | 41.730480  | 0.306842 |
|       5  | gb     |          25  | 55.868983  | 0.410801 |
|       6  | gb     |          50  | 14.038694  | 0.103226 |
|       7  | gb     |          20  | 19.810149  | 0.145663 |
|       8  | gb     |          18  | 80.074457  | 0.588783 |
|       9  | us     |          84  | 96.826158  | 0.419161 |
+----------+--------+--------------+------------+----------+
0 голосов
/ 21 мая 2019

Рассмотрите возможность использования numba

Таким образом, ваш код становится

from numba import njit

country_list = ['us','gb','ca','id']

@njit
def count(country_list):
  count = {}
  for i in country_list:
      count[i] = df_day_country[df_day_country.isin([i])]
      count[i+'_reverse'] = count[i].iloc[::-1]
      for j in range(1,len(count[i+'_reverse'])): 
          count[i+'_reverse']['count'].iloc[j] = count[i+'_reverse']['count'][j-1:j+1].sum()
      for k in range(1,len(count[i])): 
          count[i][revenue_sum].iloc[k] = count[i][revenue_sum][k-1:k+1].sum()

      count[i]['APRU'] = count[i][revenue_sum] / count[i]['count'][0]/100
  return count

Numba значительно ускоряет цикл Python и находится в процессе интеграции в более тяжелыйдежурные библиотеки Python, такие как Scipy.Deffinetly дать это посмотреть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...