Уведомления

Группа в Telegram: @pythonsu

#1 Июнь 11, 2020 16:52:34

Egorro13
Зарегистрирован: 2019-04-16
Сообщения: 105
Репутация: +  5  -
Профиль  

Пара вопросов по pandas

Приветствую!
Подскажите плиз по основам pandas: начал недавно изучать, пытаюсь набить руку - переписать скрипты по работе, но столкнулся с определенным затыком.
Требуется примерно такое поведение:

 lst =[['n1', 1, 2, 3], ['n2', 11, 22, 33], ['n1', 1,222, 333], ['n2', 11, 333, 5]]
res = {}
for line in lst:
    name = ':'.join(map(str, line[0:2]))
    res.setdefault(name, 0)
    res[name] += line[2] if line[3] < 10 else 0
print(res)
Т.е. часть столбцов в таблице объединяются в идентификатор, остальные сопоставляются с этим идентификатором для использования в дальнейшем, но значения одного столбца выбираются в зависимости от значений другого. Попытался повторить этот же пример в pandas:
 df = pd.DataFrame([['n1', 1, 2, 3], ['n2', 11, 22, 33], ['n1', 1,222, 333], ['n2', 11, 333, 5]], columns=['nm1', 'nm2', 'v1', 'v2'])
df['name'] = df.iloc[:, :2].apply(lambda r: ':'.join(r.values.astype(str)), axis=1)
Насчет формирования name - возможно, есть более изящный вариант, пока не нашел ничего. Дальше - в упор не понимаю, как правильно действовать, никакой толком информации по вопросу пока не нашел. Знаю, как выполнить групповую выборку names = df.groupby('name'), знаю как получить из нее суммы значений в столбцах, но как при этом подменять определенные значения нулем?
Пробую тупо фильтровать:
 df_filtered = df.loc[:, df['v2'] < 10]  # IndexingError: Unalignable boolean Series provided as indexer (index of the boolean Series and of the indexed object do not match).
df_filtered = df[df['v2'] < 10]  # работает без ошибки
Рекомендуемый везде loc почему-то вообще не работает, пока формулировал вопрос - обнаружил, что просто через указание столбца ошибка пропадает…
Дальше написал:
 names = df_filtered.groupby('name')['v1'].sum()
Частично работает, но при этом в df_filtered могут попадать уже не все идентификаторы, если для них не находятся значения, а должен все равно присутствовать 0. Еще приходило в голову создать отдельный столбец и в 2 захода заполнять его - сначала дублировать v1, затем заполнять нулем по фильтру, типа такого:
 df['v11'] = df['v1']
df['v11'][df['v2'] > 10] = 0
names = df.groupby('name')['v11'].sum()
Вроде и заработало - прямо сейчас, пока вопрос писал, на ходу наковырял с 134-й за 3 дня попытки, но как-то криво воспринимается - явно должен быть более правильный способ. Подскажите плиз, как такая операция грамотно выполняется и в чем причина IndexingError? Заранее благодарю.

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version