Convert column values to lower case only if they are string
What is the type of these columns to begin with? object
? If so, you should just convert them:
df['my_col'] = df.my_col.astype(str).str.lower()
MVCE:
In [1120]: df
Out[1120]:
Col1
0 VIM
1 Foo
2 test
3 1
4 2
5 3
6 4.5
7 OSX
In [1121]: df.astype(str).Col1.str.lower()
Out[1121]:
0 vim
1 foo
2 test
3 1
4 2
5 3
6 4.5
7 osx
Name: Col1, dtype: object
In [1118]: df.astype(str).Col1.str.lower().dtype
Out[1118]: dtype('O')
If you want to do arithmetic on these rows, you probably shouldn't be mixing str
s and numeric types.
However, if that is indeed your case, you may typecast to numeric using pd.to_numeric(..., errors='coerce')
:
In [1123]: pd.to_numeric(df.Col1, errors='coerce')
Out[1123]:
0 NaN
1 NaN
2 NaN
3 1.0
4 2.0
5 3.0
6 4.5
7 NaN
Name: Col1, dtype: float64
You can work with the NaNs, but notice the dtype
now.
The test in your lambda function isn't quite right, you weren't far from the truth though:
df.apply(lambda x: x.str.lower() if(x.dtype == 'object') else x)
With the data frame and output:
>>> df = pd.DataFrame(
[
{'OS': 'Microsoft Windows', 'Count': 3},
{'OS': 'Mac OS X', 'Count': 4},
{'OS': 'Linux', 'Count': 234},
{'OS': 'Dont have a preference', 'Count': 0},
{'OS': 'I prefer Windows and Unix', 'Count': 3},
{'OS': 'Unix', 'Count': 2},
{'OS': 'VMS', 'Count': 1},
{'OS': 'DOS or ZX Spectrum', 'Count': 2},
]
)
>>> df = df.apply(lambda x: x.str.lower() if x.dtype=='object' else x)
>>> print(df)
OS Count
0 microsoft windows 3
1 mac os x 4
2 linux 234
3 dont have a preference 0
4 i prefer windows and unix 3
5 unix 2
6 vms 1
7 dos or zx spectrum 2