【问题标题】:replacing data frame values with conditions用条件替换数据框值
【发布时间】:2017-09-29 07:42:31
【问题描述】:

我要完成的是查看金额列中的值的条件检查。 如果 df['amount'] 中的值小于 200k,则什么也不做。 如果 df['amount'] 中的值大于或等于 200k,则将对应的值替换为以月为单位的值或 36.00,以较大者为准。

import pandas as pd
df['amount'] = [332374.00, 22250.75, 45282.10, 339720.00, 1100.00, 40000.00, 15000.00, 207820.00, 497432.00]
df['months'] = [18.00, 17.00, 16.00, 46.00, 14.00, 13.00, 13.00, 13.00, 12.00]
df['checks'] = [1.00, 0.00, 0.00, 1.00, 0.00, 0.00, 0.00, 1.00, 1.00]

所需的输出是如下所示的数据集。

amount      months  checks
332374.00   36.00   1.00
22250.75    17.00   0.00
45282.10    16.00   0.00
339720.00   46.00   1.00
1100.00     14.00   0.00
40000.00    13.00   0.00
15000.00    13.00   0.00
207820.00   36.00   1.00
497432.00   36.00   1.00

【问题讨论】:

    标签: python python-3.x pandas


    【解决方案1】:

    您可以只使用loc 来查找金额超过您的 200k 阈值且月数小于 36 的实例。然后将这些值设置为 36。

    df.loc[(df['amount'] >= 200000) & (df['months'] < 36), 'months'] = 36
    >>> df
          amount  months  checks
    0  332374.00      36       1
    1   22250.75      17       0
    2   45282.10      16       0
    3  339720.00      46       1
    4    1100.00      14       0
    5   40000.00      13       0
    6   15000.00      13       0
    7  207820.00      36       1
    8  497432.00      36       1
    

    时间

    使用assign 会更慢,因为您必须复制整个数据框,然后分配新列。使用loc 会更快。

    这是这个小数据集的时间安排:

    %timeit df.assign(months=df.months.mask(df.amount.ge(2E5), np.maximum(df.months, 36)))
    # 1000 loops, best of 3: 1.01 ms per loop
    
    %timeit df.loc[(df['amount'] >= 200000) & (df['months'] < 36), 'months'] = 36
    # 1000 loops, best of 3: 838 µs per loop
    

    【讨论】:

    • 很好的解释!我经常使用assign,这样我就不会覆盖我的数据框。但这是您可能想要覆盖当前数据帧的一个重要原因。
    • 谢谢!这是对我有用的解决方案。我只是想对你们俩说声谢谢,感谢你们的帮助。非常酷的实现。
    【解决方案2】:

    pd.Series.mask 允许您在cond 参数中传递的True 值的位置屏蔽系列值。您还可以传递 other 参数来提供值以替换被屏蔽的值。我使用np.maximum 生成other 值。

    df.assign(months=df.months.mask(df.amount.ge(2E5), np.maximum(df.months, 36)))
    
          amount  months  checks
    0  332374.00    36.0     1.0
    1   22250.75    17.0     0.0
    2   45282.10    16.0     0.0
    3  339720.00    46.0     1.0
    4    1100.00    14.0     0.0
    5   40000.00    13.0     0.0
    6   15000.00    13.0     0.0
    7  207820.00    36.0     1.0
    8  497432.00    36.0     1.0
    

    另请参阅pd.Series.where,因为我们可以执行相同的任务:

    df.assign(months=df.months.where(df.amount.lt(2E5), np.maximum(df.months, 36)))
    
          amount  months  checks
    0  332374.00    36.0     1.0
    1   22250.75    17.0     0.0
    2   45282.10    16.0     0.0
    3  339720.00    46.0     1.0
    4    1100.00    14.0     0.0
    5   40000.00    13.0     0.0
    6   15000.00    13.0     0.0
    7  207820.00    36.0     1.0
    8  497432.00    36.0     1.0
    

    我们也可以使用相同的逻辑执行此任务,但使用numpy.where

    a = df.amount.values
    m = df.months.values
    df.assign(months=np.where(a < 2E5, m, np.maximum(m, 36)))
    
          amount  months  checks
    0  332374.00    36.0     1.0
    1   22250.75    17.0     0.0
    2   45282.10    16.0     0.0
    3  339720.00    46.0     1.0
    4    1100.00    14.0     0.0
    5   40000.00    13.0     0.0
    6   15000.00    13.0     0.0
    7  207820.00    36.0     1.0
    8  497432.00    36.0     1.0
    

    【讨论】:

    • 非常感谢。虽然我选择了其他解决方案,但我感谢您的时间和详细的解释。我将不得不阅读更多的分配和掩码。
    • 没问题,很高兴你找到了答案。
    猜你喜欢
    • 2019-07-08
    • 2021-04-13
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 2020-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多