【问题标题】:Applying/Composing a function N times to a pandas column, N being different for each row将函数应用/组合 N 次到 pandas 列,每行 N 不同
【发布时间】:2020-03-31 14:01:37
【问题描述】:

假设我们有这个简单的 pandas.DataFrame:

import pandas as pd

df = pd.DataFrame(
  columns=['quantity', 'value'],
  data=[[1, 12.5], [3, 18.0]]
)

>>> print(df)
   quantity  value
0         1   12.5
1         3   18.0

我想创建一个新列,例如 modified_value,它将函数 N 次应用于 value 列,N 是 quantity 列。 假设函数为new_value = round(value/2, 1),预期结果为:

   quantity  value  modified_value
0         1   12.5            6.2   # applied 1 time
1         3   9.0             1.1   # applied 3 times, 9.0 -> 4.5 -> 2.2 -> 1.1

这样做的优雅/矢量化方式是什么?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    你可以写一个自定义的repeat函数,然后使用apply:

    def repeat(func, x, n):
        ret = x
        for i in range(int(n)):
            ret = func(ret)
    
        return ret
    
    def my_func(val): return round(val/2, 1)
    
    df['new_col'] = df.apply(lambda x: repeat(my_func, x['value'], x['quantity']), 
                             axis=1)
    
    # or without apply
    # df['new_col'] = [repeat(my_func, v, n) for v,n in zip(df['value'], df['quantity'])]
    

    【讨论】:

    • 谢谢,这个解决方案就像一个魅力。出于好奇,您为什么要在列表理解上使用apply?
    • apply 有时很方便。例如,如果您的函数从一行中获取更多值,则键入 zip(df['col1'], df['col2'],...) 可能会令人厌烦。对很多人来说df.apply(func, axis=1) 比[func(row) for id, row in df.iterrows()] 更具可读性。另外,apply 返回一个带有相应索引的系列,这很有用。
    【解决方案2】:

    使用reduce:

    from functools import reduce
    def repeated(f, n):
        def rfun(p):
            return reduce(lambda x, _: f(x), range(n), p)
        return rfun
    

    def myfunc(value): return  round(value/2, 1)
    

    df['modified_valued'] = df.apply(lambda x: repeated(myfunc,
                                                        int(x['quantity']))(x['value']),
                                     axis=1)
    

    我们也可以使用列表推导代替apply

    df['modified_valued'] = [repeated(myfunc, int(quantity))(value) 
                             for quantity, value in zip (df['quantity'], df['value'])]
    

    输出

       quantity  value  modified_valued
    0         1   12.5              6.2
    1         3   18.0              2.2
    

    【讨论】:

    • apply 是for循环的另一种布局优雅/矢量化
    • 感谢您的回答。因为@quang-hoang 提出了一个没有额外导入的解决方案,所以我先测试了他的,并且成功了。我知道你的基于相同的概念,所以我相信它也有效。
    • map、reduce 和 filter 函数工作得很好,可能比 for 循环更好,所以我建议使用 reduce,它还提供了更简单的语法。这个解决方案得到了社区的支持,社区 https://stackoverflow.com/questions/7359828/how-to-repeat-a-function-n-times/45899449#45899449
    猜你喜欢
    • 1970-01-01
    • 2019-03-11
    • 2019-06-26
    • 1970-01-01
    • 2021-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-08
    相关资源
    最近更新 更多