【问题标题】:Using if else statements on lambda expressions on a pandas data frame based on column names在基于列名的 pandas 数据帧上对 lambda 表达式使用 if else 语句
【发布时间】:2018-11-06 15:16:17
【问题描述】:

我有一个数据框 df,如下所示:

import pandas as pd
df = pd.DataFrame({'a':[78.78, 77.26], 'b':[94.47,94.06], 'c':[0.72, 0.71], 'd':[0.19, 0.29]})

对于列abc,我想提取(到列表中)最小值,而对于列d,我想获得最大值,即:

[77.26, 94.06, 0.71, 0.29]

我主要是想用 lambda 表达式来完成这项工作

例如,要获取所有最小值,我可以:

df.apply(lambda x:x.min(), axis = 0)

我想到了类似的东西(当然它不起作用):

df_final.apply(lambda x:x.max() if x =='d' else x.min(), axis = 0)

我发现 this question 正在做类似的事情,尽管条件语句基于每列的 ,而我希望我的 if else 语句基于列名。事情是x 即可迭代对象不是列名。然后如何根据列名应用带有 lambda 函数的 if else 条件?

【问题讨论】:

标签: python python-3.x pandas if-statement lambda


【解决方案1】:

使用numpy.where:

a = np.where(df.columns == 'd', df.max(), df.min()).tolist()
print (a)
[77.26, 94.06, 0.71, 0.29]

【讨论】:

    【解决方案2】:

    一般情况下,尽量不要使用apply,因为它不执行向量化操作(即它很慢)。

    在这里,您只需选择所需的列并对列表求和

    min_cols = ['a', 'b', 'c']
    max_cols = ['d']
    
    >>> df[min_cols].min().tolist() + df[max_cols].max().tolist()
    [77.26, 94.06, 0.71, 0.29]
    

    【讨论】:

      【解决方案3】:

      agg 与字典一起使用:

      df.agg({'a':'min','b':'min','c':'min','d':'max'}).tolist()
      

      输出:

      [77.26, 94.06, 0.71, 0.29]
      

      【讨论】:

        【解决方案4】:

        您可以在系列上使用name 属性:

        df.apply(lambda x: x.max() if x.name == 'd' else x.min())
        #a    77.26
        #b    94.06
        #c     0.71
        #d     0.29
        #dtype: float64
        

        Timings 供您参考,假设您没有很多列:

        小数据框:

        df = pd.DataFrame({'a':[78.78, 77.26], 'b':[94.47,94.06], 'c':[0.72, 0.71], 'd':[0.19, 0.29]})
        ​    
        %timeit df.apply(lambda x: x.max() if x.name == 'd' else x.min()).tolist()
        # 770 µs ± 9.88 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
        
        %timeit pd.np.where(df.columns == 'd', df.max(), df.min()).tolist()
        # 268 µs ± 7.93 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
        
        %timeit df.agg({'a':'min','b':'min','c':'min','d':'max'}).tolist()
        # 814 µs ± 22.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
        
        %timeit df[min_cols].min().tolist() + df[max_cols].max().tolist()
        # 1.02 ms ± 11.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
        
        %timeit df.describe().loc['min','a':'c'].tolist()+df.describe().loc['max',['d']].tolist()
        # 18.7 ms ± 317 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
        

        大数据框:

        df = pd.DataFrame({'a':[78.78, 77.26], 'b':[94.47,94.06], 'c':[0.72, 0.71], 'd':[0.19, 0.29]})
        ​
        df = pd.concat([df] * 10000)
        
        %timeit df.apply(lambda x: x.max() if x.name == 'd' else x.min()).tolist()
        # 1.03 ms ± 16.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
        
        %timeit pd.np.where(df.columns == 'd', df.max(), df.min()).tolist()
        #1.81 ms ± 27.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
        
        %timeit df.agg({'a':'min','b':'min','c':'min','d':'max'}).tolist()
        # 1.07 ms ± 13.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
        
        %timeit df[min_cols].min().tolist() + df[max_cols].max().tolist()
        # 1.9 ms ± 30.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
        
        %timeit df.describe().loc['min','a':'c'].tolist()+df.describe().loc['max',['d']].tolist()
        # 25.7 ms ± 752 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
        

        【讨论】:

        • 请注意:时间具有误导性,因为“大数据框”和“小数据框”都只有 4 列。例如,如果您有相同的代码,但 dfdf.Tapply 的性能会非常糟糕,而其他解决方案会保持相似的时间
        • @RafaelC 是的。这确实假设没有很多列。如果不是很多,也许最好说有实际案例,apply 方法是完美的。
        【解决方案5】:

        使用describe

        df.describe().loc['min','a':'c'].tolist()+df.describe().loc['max',['d']].tolist()
        Out[276]: [77.26, 94.06, 0.71, 0.29]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-05-27
          • 2023-04-03
          • 2014-09-02
          • 1970-01-01
          • 1970-01-01
          • 2020-07-09
          • 1970-01-01
          相关资源
          最近更新 更多