Я делаю некоторую обработку на естественном языке, и у меня есть MultiIndexed DataFrame, который выглядит примерно так (за исключением того, что на самом деле около 3000 строк):
Title N-grams
Period Date
2015-01 2015-01-01 22:00:10 SIRF: Simultaneous Image Registration and Fusi... [@SENTBEGIN paper, paper propose, propose nove...
2015-01-02 16:54:13 Generic construction of scale-invariantly coar... [@SENTBEGIN encode, encode temporal, temporal ...
2015-01-04 00:07:00 Understanding Trajectory Behavior: A Motion Pa... [@SENTBEGIN mining, mining underlie, underlie ...
2015-01-04 09:07:45 Hostile Intent Identification by Movement Patt... [@SENTBEGIN the, the recent, recent year, year...
2015-01-04 14:35:58 A New Method for Signal and Image Analysis: Th... [@SENTBEGIN brief, brief review, review provid...
Что я хочу сделать, это подсчитатьсколько раз каждый n-грамм появляется в каждом месяце (отсюда первый индекс, «Период»).Делать это довольно просто, если это отнимает много времени (и поскольку каждая ячейка в столбце «N-грамм» является списком, я не уверен, что можно было бы многое сделать для его ускорения).Я создаю новый DataFrame для хранения счетчиков, используя этот код:
# Create the frequencies DataFrame.
period_index = ngrams.index.unique(level = "Period")
freqs = DataFrame(index = period_index)
# Count the n-grams in each period.
for period in period_index:
for ngrams_list in ngrams.loc[period, "N-grams"]:
for ngram in ngrams_list:
if not ngram in freqs.columns:
freqs[ngram] = 0
freqs.loc[period, ngram] += 1
Логика довольно проста: если рассматриваемый n-грамм уже виден (для него есть столбец в "freqs")"), увеличить счетчик на 1. Если его не было видно, создайте новый столбец с 0 для этого n-грамма, а затем увеличьте как обычно.В подавляющем большинстве случаев это работает нормально, но для крошечной доли н-грамма я получаю эту ошибку, когда цикл достигает строки приращения:
KeyError: u'the label [7 85.40] is not in the [index]'
(извините за отсутствие правильноготрассировка стека - я делаю это в блокноте Zeppelin, а Zeppelin не дает правильной трассировки стека.)
Немного больше отладки показало, что в этих случаях создание нового столбца завершается неудачномолча (то есть не работает, но и не возвращает исключение).
Возможно, стоит отметить, что в более ранней версии кода я использовал «loc» для непосредственного присвоения ячейке во вновь созданном столбце, а не для создания первого столбца, например:
if not ngram in freqs.columns:
freqs.loc[period, ngram] = 1
Я изменил это, потому что это вызывало проблемы при назначении NaN для этого n-грамма всем остальным периодам, но прямое назначение задыхалось точно на тех же n-граммах, что и с новым кодом.
Обернув строку приращения в блок try / Кроме того, я обнаружил, что ошибка чрезвычайно редкая: она встречается в течение примерно 20 из общего количества более 100 000 н-грамм в корпусе.Вот несколько примеров:
"7 85.40"
"2014 july"
"2010 3.4"
"and 77"
"1997 and"
"and 2014"
"6 2008"
"879 --"
"-- 894"
"2003 -"
"- 2014"
Большинство из 20 содержат цифры, но по крайней мере одно полностью состоит из букв (два слова разделены пробелом - его нет в списке выше, потому что я перезапустилсценарий при наборе этого вопроса, и не дошел до этого момента), и большое количество n-грамм только из цифр не вызывает проблем.Большинство проблемных включают годы, что, на первый взгляд, может указывать на некоторую путаницу с DatetimeIndex объекта DataFrame (учитывая, что DatetimeIndex принимает частичные совпадения), но это не объясняет не даты, особенно те, которыеначиная с букв.
Несмотря на маловероятность конфликта DatetimeIndex, я попробовал другой метод создания каждого нового столбца (как это предлагается в ответе на Добавление нового столбца в существующий DataFrame в пандах Python ), используя «loc», чтобы избежать путаницы между строками и столбцами:
freqs.loc[:, ngram] = Series(0, index = freqs.index)
... но это встречается точно так же, как мой исходный код, который неявно создавал каждый новый столбец, присваивая non-существующий столбец:
KeyError: u'7 85.40'
Затем я попробовал метод DataFrame.assign (предложенный в том же ответе, цитированном выше, хотя мне нужно было добавить обходной путь, предложенный ответом для панд, назначаемых с новымимя столбца в виде строки ):
kwarg = {ngram: 0}
freqs = freqs.assign(**kwarg)
Увы, это точнота же ошибка.
Кто-нибудь знает, почему это может происходить?Учитывая редкость, я полагаю, я мог бы просто проигнорировать проблемные н-граммы, но было бы хорошо понять, что происходит.