ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

df2 = df.my_channel 

df2[df2 > 20000] = 0

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

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

c
cs95

.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 的整数类型的布尔索引不是可用


l
lowtech

尝试

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 开始向您发出警告,还没有机会尝试
产生错误:/opt/anaconda3/envs/python35/lib/python3.5/site-packages/ipykernel_launcher.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame 查看注意事项文档:pandas.pydata.org/pandas-docs/stable/… """启动 IPython 内核的入口点。
@RutgerHofste 感谢您提到这一点,但另一个论点从未使用 Python3
f
fpersyn

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)

j
jpp

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

在 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'])

如果您有多个要屏蔽的条件怎么办?
@Egidius 如果有多个条件,我使用 np.select,否则使用 Pandas 中的 &| 运算符。
R
R. Shams

尝试这个:

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)


O
Ozkan Serttas

我会在 DataFrameSeries 上使用 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) 。我不知道它是否像您在下面添加的那样快。
不,仍然很慢,因为您仍在按行而不是按列操作。