如何处理缺失值并将Pandas数据框字符串列转为小写?
下面的代码不太好使。
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] 呢?因为实际的数据框很大,所以效率很重要。
10 个回答
10
应用 lambda 函数
df['original_category'] = df['original_category'].apply(lambda x:x.lower())
12
你也可以试试这个。
df= df.applymap(lambda s:s.lower() if type(s) == str else s)
13
Pandas >= 0.25: 用 str.casefold
去除大小写区别
从版本0.25开始,如果你在处理unicode数据,我建议使用“向量化”的字符串方法 str.casefold
(它对字符串和unicode都有效):
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时会更明显。以python的str.casefold
文档中的例子为例,
大小写折叠(casefolding)类似于小写转换,但更为严格,因为它旨在去除字符串中的所有大小写区别。例如,德语的小写字母
'ß'
等同于"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
28
另一种可能的解决方案,如果这一列不仅有字符串,还有数字的话,可以使用 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)
298
使用pandas的向量化字符串方法,就像文档中说的那样:
这些方法会自动排除缺失或NA的值
.str.lower()
就是第一个例子;
>>> df['x'].str.lower()
0 one
1 two
2 NaN
Name: x, dtype: object