创建一个函数以根据Pandas数据框和标签中的列执行分组和排序

时间:2018-10-10 15:57:33

标签: python pandas dataframe

HTMLCollection

我想根据Col2组将数据分为两组。但是,第一个匹配项应分配一个值,其余匹配项应分配一个不同的值。拉尔夫帮助我 创建的函数

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'])

然后做

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

但是,我需要对该函数进行两次修改。而不是val,它将从第4列中获取相应的值,然后返回一个值(如“低”到组中的第一个匹配项(基于排序的col1),然后对其余的说“ low_red”在组中匹配。

所以我的问题是如何修改函数来做到这一点?

我的输入

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

预期输出:

   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

1 个答案:

答案 0 :(得分: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,然后使用{{1}所调用的函数中的Col4从原始索引中提取相应的iloc列值}}。