我有一个 DataFrame,我想将特定列中超过某个值的值替换为零。我原以为这是实现这一目标的一种方法:
df[df.my_channel > 20000].my_channel = 0
如果我将通道复制到新的数据框中,这很简单:
df2 = df.my_channel
df2[df2 > 20000] = 0
这正是我想要的,但似乎不适用于作为原始数据帧一部分的通道。
.ix
索引器适用于 0.20.0 之前的 pandas 版本,但自 pandas 0.20.0 起,.ix
索引器已被弃用,因此您应该避免使用它。相反,您可以使用 .loc
或 iloc
索引器。您可以通过以下方式解决这个问题:
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 > 20000
为 True
的行,而 df.loc[mask, column_name] = 0
将值 0 设置为所选行,其中 mask
保存在名称为 column_name
的列中。
更新: 在这种情况下,您应该使用
loc
,因为如果您使用 iloc
,您将得到一个 NotImplementedError
,告诉您基于整数类型的 iLocation 布尔索引不可用。
尝试
df.loc[df.my_channel > 20000, 'my_channel'] = 0
注意: 自 v0.20.0 起,
ix
已被弃用,取而代之的是 loc
/ iloc
。
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)
原始数据帧不更新的原因是因为链式索引可能会导致您修改数据帧的副本而不是视图。 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'])
试试这个:
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)
我会在
lambda
的 Series
上使用 DataFrame
函数,如下所示:
f = lambda x: 0 if x>100 else 1
df['my_column'] = df['my_column'].map(f)
我并不认为这是一种有效的方法,但效果很好。