我有一个DataFrame,我想用零替换超过某个值的特定列中的值。我曾认为这是实现此目的的一种方式:
df[df.my_channel > 20000].my_channel = 0
如果我将通道复制到一个新的数据帧中,那就很简单:
df2 = df.my_channel
df2[df2 > 20000] = 0
这正是我想要的,但似乎无法与原始DataFrame中的通道一起使用。
我有一个DataFrame,我想用零替换超过某个值的特定列中的值。我曾认为这是实现此目的的一种方式:
df[df.my_channel > 20000].my_channel = 0
如果我将通道复制到一个新的数据帧中,那就很简单:
df2 = df.my_channel
df2[df2 > 20000] = 0
这正是我想要的,但似乎无法与原始DataFrame中的通道一起使用。
.ix
索引器对于pandas 0.20.0之前的版本工作正常,但自从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
条件的行,而df.loc[mask, column_name] = 0
则将值0赋给那些在column_name
列中mask
为真的行。
更新:
在这种情况下,应该使用loc
,因为如果你使用iloc
,你将会得到一个NotImplementedError
,告诉你基于位置的整数类型布尔索引不可用。
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)
在 pandas 对象中设置值时,必须注意避免所谓的链式索引。
您有几个替代方案:
loc
+ 布尔索引loc
可用于设置值并支持布尔掩码:
df.loc[df['my_channel'] > 20000, 'my_channel'] = 0
掩码
+ 布尔索引您可以为您的系列分配值:
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'])
&
和 |
运算符,如果有多个条件则使用 np.select
。 - Asclepius我会像这样在DataFrame
的Series
上使用lambda
函数:
f = lambda x: 0 if x>100 else 1
df['my_column'] = df['my_column'].map(f)
loc
,像这样 df.loc[: , 'my_column'] = df['my_column'].map(f)
。我不知道它是否像您下面添加的那些一样快。 - Ozkan Serttas我想通过将数据框的值与列表进行比较来执行相同的操作:
df.loc[df['value'] in [1,2,3], 'another_column'] = 'yes'
到目前为止,我得到了一个错误。
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
TypeError: argument of type 'bool' is not iterable