ny_quant: (Default)
[personal profile] ny_quant
Будь проклят тот день, когда я сел за баранку этого пылесоса! (с)

Я уже не буду говорить по сотому разу про семантику питона, индентацию и неудобный дебаггер. Самая феноменальная черта питона это непредсказуемое поведение, когда буквально один и тот же (скопипащенный) код в одном месте работает, а в другом нет, и понять в чем дело нельзя от слова никак. Сегодня у меня выдался особенно интересный день, в том смысле, что удалось наступить на одни и те же грабли дважды. Причем второй раз обошлось даже без копипасты, а прямо в одном и том же месте в цикле. Жил да был один dataframe, никого не трогал, починял примус. В одном месте к нему применялась операция groupby. И все шло хорошо пока я не поменял один из параметров, которые контролируют процесс наполнения этого dataframe. И вдруг ни с того ни с сего привет из черного ящика:

File "C:\Users\...\AppData\Local\Programs\Python\Python38\lib\site-packages\pandas\core\groupby\groupby.py", line 747, in get_group
raise KeyError(name)

Что-то где-то пошло не так, очевидно гораздо раньше, чем случилась ошибка. Дай думаю выведу данные на экран - может пойму в чем дело. Код выглядел так:

print(pos)
positions = pos.groupby(by='sign')
print(positions)
longs = positions.get_group(1)

Цикл этот проработал очень много раз без проблем. На предыдущей перед обломом итерации напечаталось:

... ......exdate ......strike. sign
619 20170616.0 2200.0 1.0
620 20170616.0 2200.0 1.0
<много похожих строк>
792 20170421.0 2475.0 -1.0
793 20170421.0 2475.0 -1.0

pandas.core.groupby.generic.DataFrameGroupBy object at 0x000001DB90D0A760

(Точки я добавил в тело поста, чтобы подравнять заголовки колонок.) А в последний раз вот что:

... ......exdate ......strike. sign
619 20170616.0 2200.0 1.0
620 20170616.0 2200.0 1.0
<много похожих строк>
817 20170616.0 2445.0 -1.0
818 20170616.0 2445.0 -1.0

Empty DataFrame
Columns: [exdate, strike, sign]
Index: []

Empty DataFrame, вон оно как! Понятно теперь почему оттуда ничего нельзя вынуть и оно ломается. Но почему оно пустое??!! Колонка 'sign' есть? Есть. Числа в ней есть? Есть, причем в каждой строчке. Так какого же черта??? И что вообще люди делают в таких случаях? Идти дебаггером в библиотеку и искать почему оно ломается в groupby.py?

Пока что я схитрил и вместо

positions = pos.groupby(by='sign')
longs = positions.get_group(1)

написал

longs = pos[pos['sign'] > 0]

Это отлично сработало, причем для тех параметров, при которых groupby() работал без аварии, результаты получились идентичные. Это, конечно, хорошо, но не покидает ощущение, что ходишь по минному полю как ночью по тайге. Хотелось бы все же по ходу чему-то научиться и что-то понять. Особенно как искать черную кошку в темной комнате.

В комментарии особенно приглашается добродетельный юзер [livejournal.com profile] laoxia, который научил меня первым шагам с dataframe, а также все кто умеет питонить, особенно [livejournal.com profile] nefedor. Также я думаю, что скорее всего разбираются в теме [livejournal.com profile] misha_b и [livejournal.com profile] kobak. Извините если отвлек от важных дел.

Date: 2022-06-29 11:43 pm (UTC)
From: [identity profile] nefedor.livejournal.com
Я вообще в Пандас не работал, я в numpy.
Но я думаю, что у тебя где-то в данных есть бяка. И в той строке где бяка, sign не 1 и не -1. В результате оно делает еще одну группу с sign=something_strange но строку туда не добавляет, так как порченную строку ей добавлять неохота - получается пустая категория, на что она и жалуется.
Вот за это я не люблю DataFrames :)
Вторая версия: у тебя категории по floating point, какой-то sign может быть не 1.0 в точности, а 1.0 + 1.e-alot или что-то похожее. Но скорее всего не это, а предыдущее.
Чтобы проверить ты можешь сделать set или dict:
d = {} # or s = set()
for row in data:
. . sign = row[-1]
. . d[sign] = 3.1415 # or s.add(sign)
а потом распечатать какие ключи получились:
print(d.keys()) # or print(s)
И если там есть бяка в sign, ты ее увидишь.

Как вообще бороться с такими вещами: гуглить.
Вот, например по "pandas groupby gives empty dataframe":
https://stackoverflow.com/questions/62303505/group-by-returns-empty-dataframe-and-no-error
https://github.com/pandas-dev/pandas/issues/743

Edited Date: 2022-06-29 11:44 pm (UTC)

Date: 2022-06-30 12:20 am (UTC)
From: [identity profile] ny-quant.livejournal.com
Спасибо!

Я проверил: все 1.0 или -1.0, хотя я и не понимаю какая разница, т.к. groupby должен группировать в любом случае, нет?

Да и не может там быть больше ничего, т.к. все записи добавляются в dataframe командами

pos.loc[posIndex] = [exdate, strike, 1]
pos.loc[posIndex] = [exdate, strike, -1]

Я вообще-то гуглил но ничего толкового не нашел. Завтра попробую почитать то, что нашел ты. По первой ссылке пока что ничего не понял. Не владею ни лямбдами ни join.

Date: 2022-06-30 12:47 am (UTC)
From: [identity profile] nefedor.livejournal.com
Еще пишут, названия колонок могут быть проблемой:
https://stackoverflow.com/questions/56815086/pandas-groupby-is-giving-keyerror-even-when-the-key-exists

И тут что-то заумное про индексы:
https://github.com/modin-project/modin/issues/1900
(deleted comment)

Date: 2022-06-30 03:34 am (UTC)
From: [identity profile] ny-quant.livejournal.com
Виноват, не въезжаю. Что означает эта странная фраза собака - друг человека ?

df = df.to_numpy()
df = pd.DataFrame(df)

Такое впечатление, что тут предлагают из dataframe перейти в какой-то NumPy array и вот там уже буде счастье? Так может мне и с самого начала не надо было с dataframe заводиться?

Вообще, если кому-то это кажется хоть в каком-то смысле нормальным, то I am all ears.

Date: 2022-06-30 09:19 am (UTC)
From: [identity profile] ticklish-frog.livejournal.com
df = df.to_numpy()

выдает квадратную матрицу чисел внутри df. То есть, грубо, "забывает" имена колонок.

df = pd.DataFrame(df)

делает DataFrame из матрицы - то есть такой хитрый способ превратить имена столбцов в 0, 1, 2, ...

Но тут надо следить, что происходит с отсутствующими элементами.

Если Вы укажете версию Pandas, то можно будет посмотреть, если есть проблема с https://github.com/modin-project/modin/pull/2125 - ну или просто попробовать

pos.groupby(by=['sign'])


Неспроста в руководстве все примеры на groupby даются со списком из одного элемента!

Date: 2022-06-30 02:50 pm (UTC)
From: [identity profile] ny-quant.livejournal.com
Футбол с нумпи забавный, но по-моему это какое-то извращение с непонятными целями.

pd.show_versions(as_json=False)

...
pandas : 1.4.2
...

pos.groupby(by=['sign']) - это то, что я и делаю. Я наверное не понял мысль.

Date: 2022-06-30 04:08 pm (UTC)
From: [identity profile] ticklish-frog.livejournal.com
Я просто пояснил, что этот переход в numpy делает. Наверное, Вы не это спрашивали.

Но весь кусок кода, что Вы показали, делает группировку и потом берет одну группу. С точки зрения code review это просто filter slicing

Date: 2022-06-30 04:19 pm (UTC)
From: [identity profile] ny-quant.livejournal.com
Да, конечно это filter slicing. Просто поразительно, что в этом простом деле что-то может пойти не так, да ещё и хрен поймешь что именно.

Date: 2022-06-30 04:32 pm (UTC)
From: [identity profile] ticklish-frog.livejournal.com
Вы делаете

by='sign'

А не
by=['sign']

Date: 2022-06-30 04:49 pm (UTC)
From: [identity profile] ny-quant.livejournal.com
О я тупой! Т.е. вместо

positions = pos.groupby(by='sgn')

надо

positions = pos.groupby(by=['sgn'])

? A в чем разница? Вообще, специально не тренированным глазом это так просто и не заметишь. К вопросу о языке.

Date: 2022-06-30 04:58 pm (UTC)
From: [identity profile] ticklish-frog.livejournal.com
Согласно документации разницы нет, но в имплементации параметра-строки был баг. Не факт, что Вы словили именно его, но все же.

Date: 2022-06-30 05:01 pm (UTC)
From: [identity profile] ny-quant.livejournal.com
Разобрался:
https://ny-quant.livejournal.com/959402.html?thread=13824426#t13824426

Date: 2022-06-30 01:57 pm (UTC)
From: [identity profile] aklepatc.livejournal.com
В отличие от "просто питона", всякие pandas и ml solutions очень часто требуют "подобрать правильное заклинание".

Там не то, чтобы нет чётко определенной семантики. Просто до неё очень тяжело докопаться.

Я потому и удалил свой последний комментарий, что это просто догадка. Чтобы реально вам помочь нужно зашарить ваш скрин и нам с вами вмести потупить в него пару часов. Я, кстати, могу попробовать если вы можете и хотите такое...
Edited Date: 2022-06-30 02:00 pm (UTC)

Date: 2022-06-30 02:18 pm (UTC)
From: [identity profile] ny-quant.livejournal.com
Спасибо, давайте мы это пока что отложим. Я завтра утром уезжаю, сегодня надо собираться, так что времени будет мало. Если ничего больше не придумается, можно будет попробовать на следующей неделе. Как шэрить скрин в домашней обстановке я тоже не знаю, кстати.

Date: 2022-06-30 03:25 pm (UTC)
From: [identity profile] Алексей Орлов (from livejournal.com)
>> Как шэрить скрин в домашней обстановке я тоже не знаю, кстати.

PyCharm, упомянутый только что: там вообще вдвоем можно программировать, в онлайн режиме :)

Date: 2022-06-30 02:40 pm (UTC)
From: [identity profile] ny-quant.livejournal.com
Да, "подобрать правильное заклинание" очень совпадает с моими ощущениями. Только мне процедура подбора не доставляет ни малейшего удовльствия. Это не то как я бы хотел проводить свое время. Удивительно, что людям это нравится.

Date: 2022-06-30 02:51 pm (UTC)
From: [identity profile] aklepatc.livejournal.com
Это мало кому нравится, кмк. Просто работа такая.

Date: 2022-06-30 02:53 pm (UTC)
From: [identity profile] ny-quant.livejournal.com
Более того, я уже как бы подобрал правильное заклинание:

longs = pos[pos['sign'] > 0]

Чем больше я читаю обсуждение, тем больше у меня растет соблазн просто остановиться на этом и дальше не копать, т.к. прогресса пока что ровно ноль.

Date: 2022-06-30 04:04 pm (UTC)
From: [identity profile] ticklish-frog.livejournal.com
Это и есть классический способ записывать conditional slicing. Используемый Вами groupby я вижу первый раз за несколько лет :)

Date: 2022-06-30 04:16 pm (UTC)
From: [identity profile] ny-quant.livejournal.com
Ха! Опять же, чайнику очень сложно понять что хорошо, или плохо, или опасно, классическое или дикое.

Date: 2022-06-30 04:24 pm (UTC)
From: [identity profile] ticklish-frog.livejournal.com
Pandas, SkiLearn, NumPy, да и сам Python — открытые системы без гарантий. Если какой то их уголок используется всеми в хвост и гриву, то он вылизан. Если что-то есть, но не используется часто, то ожидается, что нашедший нестыковки разберётся и пошлет багфикс.

Date: 2022-07-01 02:20 am (UTC)
From: [identity profile] ny-quant.livejournal.com

Ага, понятно.

Date: 2022-06-30 03:41 am (UTC)
From: [identity profile] ny-quant.livejournal.com
Я попробовал поменять column header sign->sgn, но это не помогло.

Profile

ny_quant: (Default)
ny_quant

January 2026

S M T W T F S
    123
45 6 7 8 9 10
11 12 1314151617
18192021222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 14th, 2026 01:20 am
Powered by Dreamwidth Studios