我有一个 DataFrame,我希望替换特定列中超过值为零的值。我曾以为这是实现这一目标的一种方式:
df[df.my_channel > 20000].my_channel = 0
如果我将信道复制到一个新的数据框架中,这很简单:
df2 = df.my_channel df2[df2 > 20000] = 0
这完全符合我的要求,但似乎不能作为原始 DataFrame 的一部分使用通道。
试试看
df.loc[df.my_channel > 20000, 'my_channel'] = 0
注: 自0.20.0版以来,ix 已经被否决了有利于 loc/iloc。
ix
loc
iloc
对于0.20.0之前的熊猫版本,.ix索引器可以正常工作,但是因为熊猫版本是0.20.0,所以 .ix索引器是 不赞成,所以您应该避免使用它。相反,您可以使用 .loc或 iloc索引器。你可以通过以下方法解决这个问题:
.ix
.loc
mask = df.my_channel > 20000 column_name = 'my_channel' df.loc[mask, column_name] = 0
或者一句话,
mask帮助您选择 df.my_channel > 20000为 True的行,而 df.loc[mask, column_name] = 0将值0设置为 mask保存在名为 column_name的列中的所选行。
mask
df.my_channel > 20000
True
df.loc[mask, column_name] = 0
column_name
更新: 在这种情况下,您应该使用 loc,因为如果您使用 iloc,您将得到一个 NotImplementedError告诉您 不能对整数类型进行基于 iLocation 的布尔索引。
NotImplementedError
np.where 函数的工作原理如下:
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)
我会像这样在 DataFrame的 Series上使用 lambda函数:
DataFrame
Series
lambda
f = lambda x: 0 if x>100 else 1 df['my_column'] = df['my_column'].map(f)
我并不认为这是一种有效的方法,但它确实有效。
原始数据框架没有更新的原因是因为 链式索引法链式索引法可能导致您修改数据框架的副本而不是视图。医生给出以下建议:
在熊猫对象中设置值时,必须小心避免 所谓的链式索引。
你有几个选择:-
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)
当满足 没有条件时,可以通过分配原始序列来使用 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)
我想做同样的操作,但是通过将数据帧值与列表进行比较:
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().
但是如果我尝试任何([1,2,3]) ,我就会得到错误:
TypeError: argument of type 'bool' is not iterable