现在我正在设置我的整个名字
df["name"] = df["name"].str.lower()
我的问题是,然而,我只想str.lower()单元格不包含字符串"Foo"。
我尝试了以下操作,但不工作:
df["name"] = df["name"](lambda x: str(x) if "Foo" in str(x) else str.lower(x))
TypeError: 'Series' object is not callable
列表推导式的工作方式如下:
df['name'] = [str.lower(x) if x != 'Foo' else x for x in df['name']]
我对一个包含300个名字(其中100个是Foo)的列表中的其他方法分别计时1000次,并大致计时(我知道有更好的计时方法,但我在for循环之间使用了time.time())。下面是我为这些方法找到的以秒为单位的计时:
list-comprehension : 0.049
.apply : 0.179
np.where : 0.349
.loc : 0.880
可能这些方法中的一些在比300大得多的数据集上表现得更好,所以我理解这不是一个有力的测试。其他人也许能更好地说。
使用.loc
:
df.loc[~ df['name'].str.contains('Foo'), 'name'] =
df.loc[~ df['name'].str.contains('Foo'), 'name'].str.lower()
np.where
函数也可以在这里工作,如下所示:
import numpy as np
df['name'] = np.where(df['name'].str.contains('Foo'),df['name'],df['name'].str.lower())
在您的解决方案中缺少Series.apply
:
df["name"] = df["name"].apply(lambda x: str(x) if "Foo" in str(x) else str.lower(x))
或使用Series.str.contains
并仅对过滤行应用小写字母,~
用于测试NOT
匹配掩码:
m = df["name"].str.contains('Foo')
df.loc[~m, "name"] = df.loc[~m, "name"].str.lower()
df[~df["name"].str.contains("Foo")]['name'].str.lower()
术语df[~df["name"].str.contains("Foo")]
将返回name
列中没有Foo
的DataFrame。之后,将列name
下移剩余项。