如何小写熊猫数据框字符串列,如果它有缺失的值?

下面的代码不起作用。

import pandas as pd
import numpy as np
df=pd.DataFrame(['ONE','Two', np.nan],columns=['x'])
xLower = df["x"].map(lambda x: x.lower())

我应该如何调整它以得到 xLower = [‘ one’,‘ two’,np.nan ] ? 由于实际数据框架非常庞大,因此效率非常重要。

295119 次浏览

一个可能的解决办法:

import pandas as pd
import numpy as np


df=pd.DataFrame(['ONE','Two', np.nan],columns=['x'])
xLower = df["x"].map(lambda x: x if type(x)!=str else x.lower())
print (xLower)

结果就是:

0    one
1    two
2    NaN
Name: x, dtype: object

不知道效率如何。

使用熊猫 向量化字符串方法; 如文件所示:

这些方法自动排除缺失/NA 值

.str.lower()是这方面的第一个例子;

>>> df['x'].str.lower()
0    one
1    two
2    NaN
Name: x, dtype: object

另一种可能的解决方案是,如果列中不仅有字符串,还有数字,那么就使用 astype(str).str.lower()to_string(na_rep=''),因为如果一个数字不是字符串,那么当它降低时将返回 NaN,因此:

import pandas as pd
import numpy as np
df=pd.DataFrame(['ONE','Two', np.nan,2],columns=['x'])
xSecureLower = df['x'].to_string(na_rep='').lower()
xLower = df['x'].str.lower()

那么我们有:

>>> xSecureLower
0    one
1    two
2
3      2
Name: x, dtype: object

而不是

>>> xLower
0    one
1    two
2    NaN
3    NaN
Name: x, dtype: object

编辑:

如果你不想失去 NaN,那么使用 map 会更好,(来自@wojciech-walczak 和@cs95评论)它看起来像这样

xSecureLower = df['x'].map(lambda x: x.lower() if isinstance(x,str) else x)

复制“数据框架”列,然后简单地应用

df=data['x']
newdf=df.str.lower()

你也可以试试这个,

df= df.applymap(lambda s:s.lower() if type(s) == str else s)

可能用了列表内涵

import pandas as pd
import numpy as np
df=pd.DataFrame(['ONE','Two', np.nan],columns=['Name']})
df['Name'] = [str(i).lower() for i in df['Name']]


print(df)

熊猫 > = 0.25: 使用 str.casefold删除大小写区别

从0.25版开始,如果要处理 unicode 数据(不管是字符串还是 unicode,它都可以工作) ,我建议使用“向量化”字符串方法 强 > str.casefold:

s = pd.Series(['lower', 'CAPITALS', np.nan, 'SwApCaSe'])
s.str.casefold()


0       lower
1    capitals
2         NaN
3    swapcase
dtype: object

另请参阅相关的 GitHub 问题 GH25405

casefold可以进行更积极的折叠比较,它还可以优雅地处理 NaN (就像 str.lower一样)。

但为什么这样更好呢?

从 Unicode 中可以看出区别,

折叠类似于小包装,但更具侵略性,因为它 用于删除字符串中的所有大小写区别。例如, 德文小写字母 'ß'等同于 "ss" 已经是小写的,lower()不会对 'ß'; casefold()做任何事情 转换成 "ss"

比较 lower的输出,

s = pd.Series(["der Fluß"])
s.str.lower()


0    der fluß
dtype: object

对阵 casefold,

s.str.casefold()


0    der fluss
dtype: object

也请参阅 Python: lower () vs casefold ()在字符串匹配和转换为小写时

使用应用功能,

Xlower = df['x'].apply(lambda x: x.upper()).head(10)

应用 lambda 函数

df['original_category'] = df['original_category'].apply(lambda x:x.lower())

用空字符串替换缺少的值和任何其他数据类型,并将所有字符串小写:

df["x"] = df["x"].apply(lambda x: x.lower() if isinstance(x, str) else "")

用 nan 替换丢失的值和字符串以外的任何其他数据类型,并将所有字符串小写:

df["x"] = df["x"].apply(lambda x: x.lower() if isinstance(x, str) else np.nan)

保持 nan 和字符串以外的任何其他数据类型不变,并将所有字符串小写:

df["x"] = df["x"].apply(lambda x: x.lower() if isinstance(x, str) else x)

你也可以使用 map代替 apply

在速度方面,它们几乎与 df["x"] = df["x"].str.lower()df["x"] = df["x"].str.lower()相同。 但是通过应用程序/映射,您可以随心所欲地处理缺失的值。

我测试了一百万个字符串的速度。其中10% 是 nan,其余的是长度50。

数据生成: Data generation

速度比较: enter image description here