Создание функции для выполнения группировки и сортировки на основе столбцов в фрейме данных Pandas и маркировке

1
import pandas as pd

import numpy as np

df = pd.DataFrame([
[100,     'm1',   1, 4],
[200,     'm2',   7, 5], 
[120,     'm1',   4, 4],
[240,     'm2',   8, 5],
[300,     'm3',   5, 4],
[330,     'm3',   2, 4],
[350,     'm3',   11, 4],
[200,     'm4',    9, 4]],
columns=['Col1',  'Col2',   'Col3', 'Col4'])

Я хочу сгруппировать данные в две группы на основе группы Col2. Однако первому совпадению должно быть присвоено одно значение, а остальным совпадениям должно быть присвоено другое значение. Ралф помог мне создать функцию

def my_function(x, val):

    if x.shape[0]==1:
        if x.iloc[0]>val:
            return 'high'
        else:
            return 'low'

    if x.iloc[0]>val and any(i<=val for i in x.iloc[1:]):
        return 'high'
    elif x.iloc[0]>val:
        return 'med'
    elif x.iloc[0]<=val:
        return 'low'
    else:
        return np.nan

и затем

df['Col5'] = df.sort_values(['Col2','Col1']).groupby('Col2')['Col3'].transform(my_function, (4))

Однако мне нужны две модификации функции. Вместо val он примет соответствующее значение из Col 4, а затем вернет одно значение (например, "low" для первого совпадения в группе (на основе отсортированного col1), а затем скажем "low_red" для остальной части совпадений в группе.

Итак, мой вопрос в том, как изменить функцию для этого?

Мои данные:

   Col1 Col2  Col3  Col4    
   100   m1     1     4    
   200   m2     7     5    
   120   m1     4     4   
   240   m2     8     5   
   300   m3     5     4   
   330   m3     2     4    
   350   m3    11     4    
   200   m4     9     4

Ожидаемый результат:

   Col1 Col2  Col3  Col4   Col 5    
   100   m1     1     4    low    
   200   m2     7     5    med    
   120   m1     4     4    low_red    
   240   m2     8     5    med_red    
   300   m3     5     4    high    
   330   m3     2     4    high_red    
   350   m3    11     4    high_red    
   200   m4     9     4    high
  • 0
    Вы также должны включить ожидаемый результат в свой вопрос, и может быть полезно предоставить ссылку на ваш предыдущий вопрос для справки.
  • 0
    Добавил это в вопрос. Спасибо Ральф
Показать ещё 3 комментария
Теги:
pandas
dataframe

1 ответ

1
Лучший ответ

Вы можете создать функцию более высокого уровня (позвоните на нее my_function()), которая вызывается функцией transform(), которая затем вызывает функцию нижнего уровня (пусть называет ее deeper_logic()), которая применяет предыдущую логику, изложенную в вашем вопросе, например:

def my_function(group):

    val = df.iloc[group.index]['Col4']

    value = deeper_logic(group.iloc[0], val.iloc[0], group)

    return [value if i==0 else value + '_red' for i in range(group.shape[0])]

def deeper_logic(x, val, group):

    if group.shape[0]==1:
        if x>val:
            return 'high'
        else:
            return 'low'

    if x>val and any(i<=val for i in group.iloc[1:]):
        return 'high'
    elif x>val:
        return 'med'
    elif x<=val:
        return 'low'
    else:
        return np.nan

df['Col5'] = df.sort_values(['Col2','Col1']).groupby('Col2')['Col3'].transform(my_function)

Это дает:

   Col1 Col2  Col3  Col4      Col5
0   100   m1     1     4       low
1   200   m2     7     5       med
2   120   m1     4     4   low_red
3   240   m2     8     5   med_red
4   300   m3     5     4      high
5   330   m3     2     4  high_red
6   350   m3    11     4  high_red
7   200   m4     9     4      high

Обратите внимание, что transform() работает с последовательностью и возвращает NDFrame с подобным индексом, который является результатом, который мы хотим (т.е. Сохраняем индекс исходного фрейма). Таким образом, мы можем назвать transform() с нашей Col3 колонке, а затем извлечь соответствующие Col4 значения столбцов из исходного индекса с использованием iloc в вызываемой функции от transform().

  • 0
    Потрясающие. Благодарю. Я проверю и дам вам знать и приму ответ.
  • 0
    Буду признателен также за ваш upvote! Дайте мне знать, если это работает для вас
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню