Как я нахожу зависимости от модуля своего сценария Perl?

Самый быстрый метод, который я нашел до сих пор, расширяет DataFrame с помощью .iloc и назначает обратно сглаженный целевой столбец.

Учитывая обычный вход (реплицированный бит):

df = (pd.DataFrame({'name': ['A.J. Price'] * 3, 
                    'opponent': ['76ers', 'blazers', 'bobcats'], 
                    'nearest_neighbors': [['Zach LaVine', 'Jeremy Lin', 'Nate Robinson', 'Isaia']] * 3})
      .set_index(['name', 'opponent']))
df = pd.concat([df]*10)

df
Out[3]: 
                                                   nearest_neighbors
name       opponent                                                 
A.J. Price 76ers     [Zach LaVine, Jeremy Lin, Nate Robinson, Isaia]
           blazers   [Zach LaVine, Jeremy Lin, Nate Robinson, Isaia]
           bobcats   [Zach LaVine, Jeremy Lin, Nate Robinson, Isaia]
           76ers     [Zach LaVine, Jeremy Lin, Nate Robinson, Isaia]
           blazers   [Zach LaVine, Jeremy Lin, Nate Robinson, Isaia]
...

Учитывая следующие предложенные альтернативы:

col_target = 'nearest_neighbors'

def extend_iloc():
    # Flatten columns of lists
    col_flat = [item for sublist in df[col_target] for item in sublist] 
    # Row numbers to repeat 
    lens = df[col_target].apply(len)
    vals = range(df.shape[0])
    ilocations = np.repeat(vals, lens)
    # Replicate rows and add flattened column of lists
    cols = [c for c in df.columns if c != col_target]
    new_df = df.iloc[ilocations, cols].copy()
    new_df[col_target] = col_flat
    return new_df

def melt():
    return (pd.melt(df[col_target].apply(pd.Series).reset_index(), 
             id_vars=['name', 'opponent'],
             value_name=col_target)
            .set_index(['name', 'opponent'])
            .drop('variable', axis=1)
            .dropna()
            .sort_index())

def stack_unstack():
    return (df[col_target].apply(pd.Series)
            .stack()
            .reset_index(level=2, drop=True)
            .to_frame(col_target))

Я обнаружил, что extend_iloc() является самым быстрым:

%timeit extend_iloc()
3.11 ms ± 544 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit melt()
22.5 ms ± 1.25 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit stack_unstack()
11.5 ms ± 410 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
27
задан brian d foy 11 December 2008 в 19:18
поделиться

4 ответа

Вы могли вывести %INC в конце Вашего сценария. Это будет содержать все используемые и необходимые модули. Но конечно, это только будет полезно, если Вы не потребуете модулей условно (потребуйте Foo если $bar).

20
ответ дан eckes 14 October 2019 в 13:09
поделиться

Для быстрого-и-грязного, нечастого использования, эти %INC лучший способ пойти. Если необходимо сделать это с непрерывным интеграционным тестированием или чем-то более устойчивым, существуют некоторые другие инструменты для помощи.

Steffen уже упомянул Модуль:: ScanDeps.

код в Тест:: Prereq делает это, но он имеет дополнительный слой, который гарантирует что Ваш Make-файл. МН или Сборка. МН перечисляет их как зависимость. При создании Вашего , сценарии похожи на нормальное распределение Perl , который делает довольно легким проверить на новые зависимости; просто выполните набор тестов снова.

, Кроме которого, Вы могли бы использовать инструмент такой в качестве Модуль:: Извлечение:: Используйте , который анализирует статический код, ища использование, и потребуйте операторов (хотя это не найдет их в строке evals). Это получает Вас просто модули, которые Вы сказали Вашему сценарию загружать. Кроме того, как только Вы знаете, какие модули Вы загрузили, можно объединить это с David Cantrell инструмент CPANdeps, который уже создал дерево зависимостей для большинства модулей CPAN.

Примечание, что также необходимо думать о дополнительных функциях также. Ваш код в этом случае, мои не имеют их, но иногда Вы не загружаете модуль, пока Вам не нужен он:

sub foo
    {
    require Bar; # don't load until we need to use it
    ....
    }

, Если Вы не осуществляете ту функцию в своем пробном прогоне или тесте, Вы не будете видеть необходимость в Панели для той функции. Подобная проблема подходит, когда модуль загружается, различный набор модулей зависимости в различной среде (скажите, mod_perl или Windows, и так далее).

нет хорошего, автоматизированного способа протестировать дополнительные функции как этот так, можно получить их зависимости. Однако я думаю, что это должно быть в моем Списке текущих дел, так как он походит на интересную проблему.

13
ответ дан brian d foy 14 October 2019 в 13:09
поделиться

Модуль выезда:: ScanDeps и "scandeps.pl" утилита, которая идет с ним. Это может сделать помехи (и рекурсивный), анализ Вашего кода для зависимостей, а также %INC выводит или после компиляции или после запущения программы.

Обратите внимание на то, что статический источник, сканирующий всегда, допускает ошибку на стороне включения слишком многих зависимостей. (Это - сканер зависимости, используемый ПАРИТЕТОМ, и стремится быть самым легким на конечном пользователе.)

Наконец, Вы могли принять решение распределить свой сценарий как распределение CPAN. Это звучит намного более сложным, чем это действительно. Можно использовать что-то как Модуль:: Начинающий для установки основного скелета предварительного Приложения:: распределение YourScript. Поместите свой сценарий в мусорное ведро / подкаталог и отредактируйте Make-файл. МН для ссылки на все прямые зависимости. Затем для распределения Вы делаете:

  1. Make-файл жемчуга. МН
  2. сделать
  3. сделайте dist

Последний шаг генерирует хороший App-YourScript-VERSION.tar.gz Теперь, когда клиент хочет установить все зависимости, он делает следующее:

  1. Настройте клиент CPAN правильно. Просто выполните его и ответьте на вопросы. Но Вы требуете этого уже так или иначе.
  2. "tar-xz App-YourScript-VERSION.tar.gz && cd App-YourScript-VERSION"
  3. Выполненный "cpan".

Клиент CPAN теперь установит все прямые зависимости и зависимости тех дистрибутивов автоматически. В зависимости от того, как Вы настраиваете его, это будет или следовать за предпосылками рекурсивно автоматически или запрашивать с y/n каждый раз.

Как пример этого, Вы могли бы проверить несколько из Приложения::* дистрибутивы на CPAN. Я думал бы Приложение:: Ack является хорошим примером. Возможно, одно из Приложения::* дистрибутивы из моего каталога CPAN (SMUELLER).

25
ответ дан tsee 28 November 2019 в 04:38
поделиться

Сегодня я разрабатываю свои Perl-приложения как CPAN-подобные дистрибутивы с использованием Dist :: Zilla , которая может позаботиться о зависимостях через плагин AutoPrereq . Еще один интересный фрагмент кода в этой области - картон .

2
ответ дан 28 November 2019 в 04:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: