有条件更换熊猫

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

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

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

df2 = df.my_channel


df2[df2 > 20000] = 0

这完全符合我的要求,但似乎不能作为原始 DataFrame 的一部分使用通道。

374922 次浏览

试试看

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

注: 自0.20.0版以来,ix 已经被否决了有利于 loc/iloc

对于0.20.0之前的熊猫版本,.ix索引器可以正常工作,但是因为熊猫版本是0.20.0,所以 .ix索引器是 不赞成,所以您应该避免使用它。相反,您可以使用 .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 的布尔索引

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)

我会像这样在 DataFrameSeries上使用 lambda函数:

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

我并不认为这是一种有效的方法,但它确实有效。

原始数据框架没有更新的原因是因为 链式索引法链式索引法可能导致您修改数据框架的副本而不是视图。医生给出以下建议:

在熊猫对象中设置值时,必须小心避免 所谓的链式索引。

你有几个选择:-

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)

我想做同样的操作,但是通过将数据帧值与列表进行比较:

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