Каково использование рекурсивного вызова
blockquote>function(w)
вmodule.exports
?Это не рекурсивный вызов, а больше функция отложенной инициализации. В некоторых средах CommonJS, таких как Node.JS, глобальный объект не имеет свойства
document
, в то время как другие, такие как Browserify и Webpack.jQuery требует, чтобы свойство
document
инициализировалось, поэтому оно сначала проверьте, содержит ли глобальный объект свойствоdocument
. Если это так, он инициализирует немедленно, делая среду браузера CommonJS счастливой. Если это не так, он возвращает функцию, которая может быть использована для последующей инициализации jQuery. Эта функция может быть позже вызвана в поддельном окне, создавая с чем-то вроде jsdom.Какая польза от переменной
blockquote>noGlobal
?Здесь используется переменная
noGlobal
.// Expose jQuery and $ identifiers, even in // AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557) // and CommonJS for browser emulators (#13566) if ( typeof noGlobal === strundefined ) { window.jQuery = window.$ = jQuery; }
По существу, если
noGlobal
-undefined
, jQuery добавит себя к глобальному объектуwindow
. Единственный раз, когда он этого не сделает, будет загружен загрузчиком CommonJS со свойствомdocument
на глобальном объекте, таким как Browserify или Webpack. Ниже приведен вызов:noGlobal
неundefined
.factory( global, true )
Где действительно установлен
factory
и каков его тип?Переменная
factory
являетсяfunction
, и она заявлена здесь:function( window, noGlobal ) {
Это второй аргумент, переданный в IIFE .
Почему аргумент
blockquote>factory
вызывается с одним аргументом и с двумя?Поскольку JavaScript.
В JavaScript нет требования сопоставлять количество аргументов, объявленных функцией. Любые опущенные аргументы имеют значение
undefined
.Что должен содержать аргумент
blockquote>global
? (Мне жаль, что не было такого типа, как в c ++ ...)Предполагается, что он содержит глобальный объект для среды JavaScript. В браузере этот объект известен как
window
, а в узле этот объект известен какglobal
. В обеих средах использованиеthis
в глобальной области будет разрешено для глобального объекта, независимо от его глобального имени.Однако из-за некоторых сторонних оболочек, которые могут изменять область, в которой jQuery initialized, jQuery сначала проверит, доступен ли объект
window
и использует его, если он есть. Если не использовать, по умолчанию будет использоватьсяthis
.typeof window !== "undefined" ? window : this
еще один вопрос: где аргумент w, исходящий из?
blockquote>Если глобальный объект не содержит
document
, он возвращает функцию, которая принимает один аргумент,w
. Этот объект будетwindow
-подобным объектом сdocument
, который может быть создан с помощью чего-то вроде jsdom.
Используйте groupby
с лямбда-функцией для dictionaries
на reviewerName
, а затем выведите Series
для преобразования в to_dict
:
print (df)
reviewerName title reviewerRatings
0 Charles Harry Potter Book Seven News:... 3.0
1 Charles Harry Potter Boxed Set, Books... 5.0
2 Charles Harry Potter and the Sorcerer... 5.0
3 Katherine Harry Potter and the Half-Blo... 5.0
4 Katherine Harry otter and the Order of... 5.0
<ч > d = (df.groupby('reviewerName')['title','reviewerRatings']
.apply(lambda x: dict(x.values))
.to_dict())
print (d)
{
'Charles': {
'Harry Potter Book Seven News:...': 3.0,
'Harry Potter Boxed Set, Books...': 5.0,
'Harry Potter and the Sorcerer...': 5.0
},
'Katherine': {
'Harry Potter and the Half-Blo...': 5.0,
'Harry otter and the Order of...': 5.0
}
}
Есть несколько подходов. Вы можете использовать groupby
с to_dict
или перебирать строки с collections.defaultdict
. Примечательно, что последняя не не обязательно менее эффективна.
groupby
+ to_dict
Построить ряд из каждого объекта groupby
и преобразовать его в словарь, чтобы получить серию значений словаря , Наконец, преобразуйте это в словарь словарей с помощью другого вызова to_dict
.
res = df.groupby('reviewerName')\
.apply(lambda x: x.set_index('title')['reviewerRatings'].to_dict())\
.to_dict()
collections.defaultdict
Определите defaultdict
из dict
объектов и повторяйте свой кадр данных по строкам.
from collections import defaultdict
res = defaultdict(dict)
for row in df.itertuples(index=False):
res[row.reviewerName][row.title] = row.reviewerRatings
Полученный defaultdict
не нужно преобразовывать обратно в обычный dict
, так как defaultdict
является подклассом dict
.
Сравнительный анализ настроен и зависит от данных. Вы должны проверить свои собственные данные, чтобы увидеть, что работает лучше.
# Python 3.6.5, Pandas 0.19.2
from collections import defaultdict
from random import sample
# construct sample dataframe
np.random.seed(0)
n = 10**4 # number of rows
names = np.random.choice(['Charles', 'Lora', 'Katherine', 'Matthew',
'Mark', 'Luke', 'John'], n)
books = [f'Book_{i}' for i in sample(range(10**5), n)]
ratings = np.random.randint(0, 6, n)
df = pd.DataFrame({'reviewerName': names, 'title': books, 'reviewerRatings': ratings})
def jez(df):
return df.groupby('reviewerName')['title','reviewerRatings']\
.apply(lambda x: dict(x.values))\
.to_dict()
def jpp1(df):
return df.groupby('reviewerName')\
.apply(lambda x: x.set_index('title')['reviewerRatings'].to_dict())\
.to_dict()
def jpp2(df):
dd = defaultdict(dict)
for row in df.itertuples(index=False):
dd[row.reviewerName][row.title] = row.reviewerRatings
return dd
%timeit jez(df) # 33.5 ms per loop
%timeit jpp1(df) # 17 ms per loop
%timeit jpp2(df) # 21.1 ms per loop