Ответы пользователя по тегу Pandas
  • Как сравнить 2 df в Пандасе?

    Maksim_64
    @Maksim_64
    Data Analyst
    1. Если в колонке сборник (строки, числа, пропущенные значения). То это тип 'object'. Что означает python object что в свою очередь надо понимать буквально, массив состоит из python объектов.

    2. Операция сравнения двух объектов, не является однозначно трактованной операцией, в том числе и по этому в python существуют дандер методы которые позволяют переопределять операторы сравнения (вложить свой смысл что именно ты подразумеваешь по сравнением). Это я к тому что ты должен четко понимать что значит равны.

    pandas объекты поддерживают сравнение в его собственной интерпретации и поведении. Если этого достаточно
    то, все элементарно. Если сравнение используется для фильтра то такие колонки не хранят.
    df = pd.DataFrame({
        'A':[1,'a',2],
        'B':[1,'a',3]
    })
    
    df.loc[df['A'] == df['B']]

    Колонкам не обязательно быть из одного и того же фрейма, лишь бы размерность совпадала.
    Если же нужно особое понимание сравнения. То пишется функция которая принимает два массива на вход и возвращает массив булевых значений, затем этот массив используется в качестве маски, для осуществления выборки.
    Ответ написан
    Комментировать
  • Как вставить строчки в exel через pandas?

    Maksim_64
    @Maksim_64
    Data Analyst
    Важно что форматы ячеек, шрифты и тд остались прежними. Это возможно сделать?
    с учетом этого pandas будет недостаточно, проще всего с использованием openpyxl это будет сделать.
    Ответ написан
    Комментировать
  • Как объединить две таблицы в pandas?

    Maksim_64
    @Maksim_64
    Data Analyst
    pd.merge(левая таблица, правая таблица, left_on='CELL',right_on='GeranCellId ', how=method)

    где метод left, right,inner, outer, cross. Это типы джойнов.
    merge

    Ну и выбери нужные колонки, например. для левой таблицы тебе не нужны BSC и LAC, если ты по правой будешь джойнить, тебе эти колонки оттуда нужны. Выбирать нужные колонки и ставить их в желаемом порядке делают c помощью loc. фрейм.loc[:,[колонка1, колнка2, итд]]
    Ответ написан
    Комментировать
  • Почему данные не сортируются по дате?

    Maksim_64
    @Maksim_64
    Data Analyst
    1. Не помешало бы, пример несколько строк из фрейма которые не сортируются.
    2. Обратно возвращать в строку не обязательно.
    3. Методы чтения имеют параметр parse_dates для того что бы строковое представление даты перводить в тип данных datetime64
    вот небольшой примерчик
    (
        pd.DataFrame({
            'string_dates':['17.08.2024','15.08.2024','20.09.2024'],
            'values':[10,100,1000]
        })
        .assign(
            dates=lambda x: pd.to_datetime(x['string_dates'],format='%d.%m.%Y')
        )
        .sort_values(by='dates')
    )
    как видишь все сортируется, обрати внимания на типы данных. Колонку которая используется для сортировки можно дропнуть, ну или создать ее что называется "на лету".
    Ответ написан
    Комментировать
  • Как отфильтровать массив столбца датафрейма Pandas без выноса их в отдельный столбец?

    Maksim_64
    @Maksim_64
    Data Analyst
    Решений миллион.
    1. написать функцию для работы с питон списком, которая будет будет возвращать, True,False.
    2. Применить один из многочисленных методов фильтрации.

    Например
    df = pd.DataFrame({
        'userID':[25,188,79],   
        'goalsID':[[1,2,4,5],[3,6],[1,9]]
    })
    (
        df.loc[lambda x:x['goalsID'].apply(lambda x: 3 in x)]
    )
    Ответ написан
  • Как преобразовать тип данных столбца в Pandas?

    Maksim_64
    @Maksim_64
    Data Analyst
    Преобразование типов здесь не при чем.

    вот здесь ты print(df[['market_cap'] > 0])
    Ты выполняешь операцию не с массивом а со списком. Списки ['market_cap'] > 0 такого не поддерживают. Если ты хотел выбрать подсет фрейма где капитализация больше нуля то пропустил df еще один.

    print(df[df['market_cap'] > 0])
    Ответ написан
    1 комментарий
  • Как узнать, что диапазон находится в пределах нормы отклонений?

    Maksim_64
    @Maksim_64
    Data Analyst
    Колебаний относительно чего? пусть будет некое число x0. pandas псевдокод будет такой
    s - Series с временными диапазонами
    x0 - относительно чего колебания
    ((x0 - s).abs() <= 3).mean() * 100 Это количество в процентом отношении значений которые отклоняются от x0 в пределах +-3 секунд
    Ответ написан
    Комментировать
  • Неочевидное поведение расчетов на Python pandas, как такое получается?

    Maksim_64
    @Maksim_64
    Data Analyst
    x - значение ячейки в лямбде, то есть (x*q1/q0) это выполняется для каждого значения a2, где x - это каждое значение a2. (синий кейс) Во втором же случае нормальная замена на 95 квантиль любого значения ячейки а2 которое больше 95 квантиля. (красный кейс)
    Ответ написан
    1 комментарий
  • Как с помощью assign добавить в фрейм данных столбец, в котором будут индексы трех максимальных элементов из другого столбца той же записи?

    Maksim_64
    @Maksim_64
    Data Analyst
    Все довольно просто, на будущее если запутался, то предоставляй:
    1. Входные данные (фрейм)
    2 . Что хотелось бы получить.
    3. Ну и попытку решения (ее ты предоставил, пытался вопросов нет).

    Сделаю за тебя фрейм со случайными данными и затем решу вопрос.
    df = pd.DataFrame({
        'A':[np.random.randint(1,100,20) for i in range(5)],
    })

    Решение
    result = (
        df.assign(
            three_largest = lambda x: x['A'].apply(lambda x: pd.Series(x).nlargest(3).tolist()),
            three_largest_index = lambda x: x['A'].apply(lambda x: pd.Series(x).nlargest(3).index.tolist())
        )
    )

    Если захочешь разложить свои списки на отдельные колонки то используй следующий трюк.
    result[['one','two','three']] = pd.DataFrame(result['three_largest_index'].tolist(),index=result.index)
    result
    Как видишь все в разных вариациях, как удобно.
    Ответ написан
    Комментировать
  • Как правильно заменить значения в столбцах фрейма данных python pandas?

    Maksim_64
    @Maksim_64
    Data Analyst
    df = pd.DataFrame({
        'A':[[5,6,24,3],[23,11,15],[3,100]],
        'B':np.NaN
    })
    (
        df.assign(
            A_max =lambda x: x['A'].apply(max),
            B_indexmax =lambda x: x['A'].apply(lambda x: pd.Series(x).idxmax()),
        )
    )

    Пару слов.
    1. Для замены. Вместо A_max, B_index_max меняем на А и B и меняем их местами сначала B потом A. Так делать плохая практика. Не нужно тебе A и B колонки просто выкинь их отдельно, а эти переименуй.

    2. loc мощный инструмент, для выборок он у меня наверное почти в каждом запросе присутствует но для выборок Для процессирования колонок плохая практика
    df.loc[:,[колонка]] = массив, вот так старайся не делать. Используй assign, как у меня в примере.
    Ответ написан
    Комментировать
  • Не работает модель для игры камень, ножницы, бумага?

    Maksim_64
    @Maksim_64
    Data Analyst
    Вся твоя затея не имеет никакого смысла. KNeighborsClassifier - использует по умолчанию Minkowski metric, что эквивалетно для p=2, обычной Евклидовой дистанции.

    Евклидова дистанция не имеет никакого смысла - для категориальных переменных на вход, она мощный инструмент для непрерывных и бесполезный для категориальных. А у тебя именно категории stone, shears и paper которые закодировал ты правда, совершенно не правильно. Тебе тут нужен OneHotEncoder, а так ты как бы говоришь алгоритму что paper (3) чем то отличается по весу в модели чем stone (1) . В целом можно работать с так называемой Hamming distance, которая позволяет KNeighborsClassifier получать категории на вход, но scikit-learn не поддерживает ее из коробки, то есть ее можно добавить как custom metric.

    Если ты собираешься чему то научится то:
    1. Изучи примеры с объектом pipeline он позволяется осуществлять трансформации на тестовом и тренировачном датасете, внутри пайплайна.

    2. Для любого алгоритма для этой задачи необходим OneHotEncoder его прям в пайплайн встроешь. Примеры в доках scikit-learn имеются.

    3. По скольку у тебя категориальные переменные на вход, то используй алгоритмы которые базируются на деревьях решений. Все они есть в scikit-learn.
    Ответ написан
    2 комментария
  • Как посчитать и вывести уникальные значения колонок dataframe, которые имеют тип коллекции/списка?

    Maksim_64
    @Maksim_64
    Data Analyst
    С помощью цикла однозначно не придется. Встроенный инструмент есть, даже много.
    чтобы мне достать из этих столбцов уникальные значения
    Вот это не совсем понятно, может имелось ввиду из списков, уникальные, и что значит достать.

    Если у тебя твои данные в списках то можно использовать explode.
    (
        pd.DataFrame({
            'ID':[1,2],
            'genres':[['Strategy'],['Fightening','Adventure','Arcade']]
        })
        .explode('genres')
    )
    Затем unique (уникальные) value_counts (посчитать каких и сколько у тебя там) или все что угодно, опций огромное количество. Обрати внимание структура фрейма не рушится (поведение колонки ID).

    В качестве ответа. Цикл не использовать, можно все. Для более конкретного ответа. Предоставляешь игрушечный фрейм, и то что ты хочешь увидеть, на выходе. По скольку словами не очевидно, что именно ты хочешь.
    Ответ написан
    Комментировать
  • Как в pandas объединить непрерывную последовательность событий одного типа в интервал?

    Maksim_64
    @Maksim_64
    Data Analyst
    Давай по порядку пандас запрос который решает вопрос.
    (
        df
        .assign(
            groups=(df['EventType'] != df['EventType'].shift())
            .cumsum()
        )
        .groupby('groups'
        )
        .agg(
            first= pd.NamedAgg(column='EventTime',aggfunc=lambda x: np.min(x)),
            last= pd.NamedAgg(column='EventTime',aggfunc=lambda x: np.max(x)),
            EventType= pd.NamedAgg(column='EventType',aggfunc=lambda x: set(x).pop()),
            user_id=pd.NamedAgg(column='user_id',aggfunc=lambda x: set(x).pop()),
            )
        .reset_index(drop=True)
        .loc[:,['user_id','EventType','first','last']]
    )


    Ключевая история это группировка с последовательно повторяющимися значениями. Вот этот запрос по сути решает весь вопрос
    (
        df
        .groupby(
            (df["EventType"] != df["EventType"].shift())
            .cumsum()
        )
        .agg({"EventTime" : ["min", "max"]})
    )
    Остальное это манипуляции для идентичного твоему вывода (писал на скорую руку совместил агрегации с трансформациями) что не есть хорошо, я бы поработал и сделал лучше. В целом сработает и для строк, но лучше привести EventTime к типу данных datetime64[ns]. Сделать это можно
    (
        df.assign(
            EventTime=lambda x: pd.to_datetime(x['EventTime'],format='%Y-%m-%d %H:%M:%S')
        )
       ... 
    )
    Ответ написан
    4 комментария
  • Как применить функцию для всего датафрейма pandas?

    Maksim_64
    @Maksim_64
    Data Analyst
    1. Фрейм это не однородная структура данных, то есть у тебя могут быть колонки разных типов, и если ты применяешь функцию для всего фрейма (возможно применение и для подсета фрейма), ты должен быть уверен, что она применима к этим типам данным.

    2. Как следствие ты должен привести свой фрейм к такому типу данных с которым может работать твоя функция метод astype

    3. Есть три направления для применения твоей функции. Основной это метод apply он применяется к каждой строке или каждой колонке параметр axis, то есть когда ты пишешь свою кастомную функцию на вход она будет получать либо numpy массив либо pandas Series. Вообще apply для фрейма имеет довольно много интересных параметров почитай доки этого метода он реально мощный.

    4. Ты также можешь использовать pipe он работает как с Series так и с фреймаим я их часто по цепочке использую очень удобно. То есть пишешь функцию где на вход тебе фрейм приходит, оперируешь так как хочешь им. И потом ориганальный фрейм pipe(func, *args, **kwargs) и тебе приходит копия оригинального фрейма с твоими изменениями описанными в func, это очень хорошая практика.

    5. Ну и последнее самое простенькое это map применяет функцию по элементно к твоему фрейму. То есть свою кастомную функцию ты пишешь, не для numpy массива, не для pandas Series, а для каждого элемента фрейма.
    Ответ написан
    Комментировать
  • Сквозная сортировка индексов DataFrame?

    Maksim_64
    @Maksim_64
    Data Analyst
    Ну с формулировкой вопроса ты подкачал, это переформатирование фрейма с элементами сортировки подсета данного фрейма. Вообще когда решаешь такую задачу, то индексы фрейма (колонки и индекс) будут тебе мешать, надо переводить подсет данных в numpy массив и там сортировать.

    Так или иначе, задачка простая, и решается в одну строчку кода, многими способами , например вот так
    df.loc[:,['A','B','C']] = np.sort(df[['A','B','C']].values,axis=1)

    Это изменит твой фрейм как ты хочешь, или определенными вариациями данного кода.
    Ответ написан
    Комментировать
  • Как выравнивать столбцы Pandas для красивого вывода в терминале?

    Maksim_64
    @Maksim_64
    Data Analyst
    С учетом того что в родном IDE все не ровно, то на ум приходит только следующая причина. Тип данных твоих колонок 'object' или 'string' и строки содержат пробелы в начале и в конце. В общим нужно применить метод strip (удалить лишние пробелы в начале и в конце строки).
    result = df.assign(**{
        'Системы:':lambda x:x['Системы:'].str.strip(),
        'Текущий %:':lambda x:x['Текущий %:'].str.strip(),
        'Плановый %:':lambda x:x['Плановый %:'].str.strip()
    })
    print(result)

    Если речь именно об этих данных что ты приложил в примере, то в моем python IDE они выглядят вот так
    65e0b054c7d7a530628786.png
    Как видишь вполне себе ровно, это без моего кода удаления пробелов. Так как в предоставленных тобой данных нет лишних пробелов.
    Ответ написан
  • Как сгруппировать строки в DF по условию?

    Maksim_64
    @Maksim_64
    Data Analyst
    Профессиональных способов несколько например использовать resample метод. Это специализированный groupby для временной последовательности, второй это использовать groupby вместе с pd.Grouper. Приведу простенький пример.
    index = pd.date_range('1/1/2000', periods=9, freq='min')
    df= pd.DataFrame(data=np.random.randint(1,10,(9,2)), index=index, columns=['A','B'])
    df.resample('3min').agg({'A':'sum','B':'mean'})
    Я создал фрейм с индексом временная последовательность (1 мин). сгруппировал по 3минуты и применил к каждой из колонок разные аггрегирующие функции.

    Выбирать можно по любым временным интервалам. Почитай доки.
    Ответ написан
    1 комментарий
  • Почему при замене значения в DataFrame на pandas происходит ошибка, но значение меняется?

    Maksim_64
    @Maksim_64
    Data Analyst
    1. Это не ошибка, а предупреждение которому сто лет в обед, более того в зависимости от твоей версии pandas, ты можешь видеть не одно а сразу два предупреждения. В pandas давно уже целый раздел документации посвящен этому copy_on_write

    2. Детали про copy_on_write прочтешь в документации, там все расписано не хочу повторяться. Собираешься работать с pandas, ты должен знать что это такое.

    3. Правильный способ безопасно осуществить операцию, которую ты хочешь (что бы не было предупреждений и работало, как ты ожидаешь.
    pd.options.mode.copy_on_write = True
    info = {'color': ['blue', 'green', 'yellow', 'red', 'white'],
    'object': ['ball', 'pen', 'pencil', 'paper', 'mug'],
    'price': [1.2, 1.0, 0.6, 0.9, 1.7]}
    frame = pd.DataFrame(info)
    frame.loc[2,'price'] = 100 
    print(frame)

    Ну и обнови на всякий случай pandas по скольку copy_on_write будет по умолчанию установлен в True в будущих версиях.
    Ответ написан
    Комментировать
  • Как получить данные колонки Pandas?

    Maksim_64
    @Maksim_64
    Data Analyst
    Ну у тебя не много колонок, а всего одна. Элементы массива (имена колонок) идут через запятую. А все что ты заскринил, это одна строка, как следствие один элемент массива.

    Как пофиксить, ну я не знаю что у тебя там в файле, но предположу что у тебя в файле разделение на колонки происходит сивволом ';'. Как следствие тебе нужно указать параметром при чтении.
    df = df.read_csv(filename, sep=';') Ну и остальные параметры которые ты там указываешь. Решит ли это все проблемы неизвестны. Надо видеть в каком состоянии файл. Чтение файлов иногда может быть серьезной проблемой, которая потребует написания функций для проблемной части парсинга.
    Ответ написан
    1 комментарий
  • Как в сделать Pandas объединение строк группирую по определнному столбцу?

    Maksim_64
    @Maksim_64
    Data Analyst
    Ну на сам деле задачка на 5 минут, есть определенные методы заполнения пропущенных значений, 'ffill' forward fill и 'bfill' backward fill. Они и есть ключ к решению, далее группировка происходит без проблем, и дальнешее дело техники, при чем многими способами, например так.
    f = pd.DataFrame({
        'A':['a',np.NaN,np.NaN,'b',np.NaN,np.NaN,np.NaN,'v',np.NaN,np.NaN,'d',np.NaN,np.NaN],
        'B':['foo','foo','bar','bar','bar','foo','bar','foo','bar','foo','bar','foo','bar']
    })
    result = (
        df
        .groupby(df['A']
        .fillna(method='ffill'))['B']
        .apply(lambda x: ','.join(x))
        .reset_index()
    )
    result
    Ответ написан