【问题标题】:Conditional Replace Pandas有条件替换 Pandas
【发布时间】:2014-03-03 17:06:11
【问题描述】:

我有一个 DataFrame,我想用零替换特定列中超过某个值的值。我曾认为这是实现这一目标的一种方式:

df[df.my_channel > 20000].my_channel = 0

如果我将频道复制到一个新的数据框中,这很简单:

df2 = df.my_channel 

df2[df2 > 20000] = 0

这正是我想要的,但似乎不适用于作为原始 DataFrame 一部分的通道。

【问题讨论】:

  • 找到了我认为您正在寻找的东西here

标签: python pandas replace conditional-statements series


【解决方案1】:

试试

df.loc[df.my_channel > 20000, 'my_channel'] = 0

注意:从 v0.20.0 开始,ix has been deprecated 支持 loc / iloc

【讨论】:

  • 谢谢。我也找到了自己的解决方案,即: df.my_channel[df.my_channel >20000] = 0
  • @BMichell 我认为你的解决方案可能会在 0.13 开始给你警告,还没有机会尝试
  • yield 错误:/opt/anaconda3/envs/python35/lib/python3.5/site-packages/ipykernel_launcher.py:1: SettingWithCopyWarning: A value is trying to be set on a copy从 DataFrame 切片请参阅文档中的注意事项:pandas.pydata.org/pandas-docs/stable/… """启动 IPython 内核的入口点。
  • @RutgerHofste 感谢您提到这一点,但另一个论点从未使用 Python3
【解决方案2】:

.ix 索引器适用于 0.20.0 之前的 pandas 版本,但由于 pandas 0.20.0,.ix 索引器是 deprecated,所以你应该避免使用它。相反,您可以使用.lociloc 索引器。您可以通过以下方式解决此问题:

mask = df.my_channel > 20000
column_name = 'my_channel'
df.loc[mask, column_name] = 0

或者,在一行中,

df.loc[df.my_channel > 20000, 'my_channel'] = 0

mask 帮助您选择df.my_channel > 20000True 的行,而df.loc[mask, column_name] = 0 将值0 设置为mask 保存在名称为column_name 的列中的选定行。

更新: 在这种情况下,您应该使用loc,因为如果您使用iloc,您将收到NotImplementedError,告诉您基于iLocation 的整数类型的布尔索引不可用

【讨论】:

    【解决方案3】:

    np.where函数工作原理如下:

    df['X'] = np.where(df['Y']>=50, 'yes', 'no')
    

    在你的情况下,你会想要:

    import numpy as np
    df['my_channel'] = np.where(df.my_channel > 20000, 0, df.my_channel)
    

    【讨论】:

      【解决方案4】:

      我会在SeriesSeries 上使用lambda 函数,如下所示:

      f = lambda x: 0 if x>100 else 1
      df['my_column'] = df['my_column'].map(f)
      

      我不断言这是一种有效的方法,但它工作正常。

      【讨论】:

      • 这是低效的,不推荐使用,因为它在逐行操作中涉及 Python 级循环。
      • 谢谢,我想我们可以在这里使用loc,比如df.loc[: , 'my_column'] = df['my_column'].map(f)。不知道是不是和你下面加的一样快。
      • 不,仍然很慢,因为您仍在按行而不是按列操作。
      【解决方案5】:

      原始数据框未更新的原因是chained indexing 可能会导致您修改副本而不是数据框的视图。 docs 给出这个建议:

      在 pandas 对象中设置值时,必须小心避免 什么叫做链式索引。

      你有几个选择:-

      loc + 布尔索引

      loc 可用于设置值并支持布尔掩码:

      df.loc[df['my_channel'] > 20000, 'my_channel'] = 0
      

      mask + 布尔索引

      您可以分配给您的系列:

      df['my_channel'] = df['my_channel'].mask(df['my_channel'] > 20000, 0)
      

      或者您可以就地更新您的系列:

      df['my_channel'].mask(df['my_channel'] > 20000, 0, inplace=True)
      

      np.where + 布尔索引

      当您的条件满足时,您可以通过分配您的原始系列来使用 NumPy;但是,前两个解决方案更简洁,因为它们仅显式更改指定的值。

      df['my_channel'] = np.where(df['my_channel'] > 20000, 0, df['my_channel'])
      

      【讨论】:

      • 如果要屏蔽多个条件怎么办?
      【解决方案6】:

      试试这个:

      df.my_channel = df.my_channel.where(df.my_channel <= 20000, other= 0)

      df.my_channel = df.my_channel.mask(df.my_channel > 20000, other= 0)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-08
        • 1970-01-01
        相关资源
        最近更新 更多