代码之家  ›  专栏  ›  技术社区  ›  Stan

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

  •  1
  • Stan  · 技术社区  · 7 年前
    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
    

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

    但是,我需要对函数进行两个修改。它将不使用val,而是从第4列中获取相应的值,然后返回一个值(例如对组中的第一个匹配项返回“low”(基于排序后的第1列)),然后对组中的其余匹配项说“low\u 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
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   rahlf23    7 年前

    您可以创建一个更高级别的函数(我们称之为 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
    

    转换() 对序列进行操作并返回一个类似索引的NDFrame,这是我们想要的结果(即保留原始数据帧的索引)。因此,我们可以 转换() 用我们的 Col3 Col4 原始索引中的列值,使用 iloc 在从中调用的函数中 转换()