Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/amazon-s3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 仅当列值为字符串时才将其转换为小写_Python_String_Pandas_Dataframe - Fatal编程技术网

Python 仅当列值为字符串时才将其转换为小写

Python 仅当列值为字符串时才将其转换为小写,python,string,pandas,dataframe,Python,String,Pandas,Dataframe,我很难将一列转换成小写。这并不像仅仅使用: df['my_col'] = df['my_col'].str.lower() 因为我迭代了很多数据帧,其中一些(但不是全部)在感兴趣的列中同时包含字符串和整数。这会导致lower函数(如果像上面那样应用)引发异常: AttributeError: Can only use .str accessor with string values, which use np.object_ dtype in pandas 我希望评估值是否为字符串,如果是,

我很难将一列转换成小写。这并不像仅仅使用:

df['my_col'] = df['my_col'].str.lower()
因为我迭代了很多数据帧,其中一些(但不是全部)在感兴趣的列中同时包含字符串和整数。这会导致lower函数(如果像上面那样应用)引发异常:

AttributeError: Can only use .str accessor with string values, which use np.object_ dtype in pandas
我希望评估值是否为字符串,如果是,则将其转换为小写,如果不是字符串,则保持原样,而不是强制将类型设置为字符串。我认为这会奏效:

df = df.apply(lambda x: x.lower() if(isinstance(x, str)) else x)
但它不起作用。。。可能是因为我忽略了一些明显的东西,但我看不到它是什么

我的数据如下所示:

                          OS    Count
0          Microsoft Windows     3
1                   Mac OS X     4
2                      Linux     234
3    Don't have a preference     0
4  I prefer Windows and Unix     3
5                       Unix     2
6                        VMS     1
7         DOS or ZX Spectrum     2

这些列的类型是什么<代码>对象?如果是这样,您只需将其转换为:

df['my_col'] = df.my_col.astype(str).str.lower()
MVCE:

如果要对这些行执行算术运算,可能不应该混合使用
str
s和数字类型

但是,如果确实是这样的话,您可以使用
pd.to_numeric(…,errors='concurve')将类型转换为numeric


您可以使用NAN,但现在请注意
dtype

lambda函数中的测试不太正确,但您离事实并不遥远:

df.apply(lambda x: x.str.lower() if(x.dtype == 'object') else x)
使用数据帧和输出:

>>> 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

从以上两个答案来看,我认为这样做更安全:

注意
astype(str)


因为如果字符串列碰巧只包含某些行中的数字,不执行
astype(str)
将它们转换为nan。这可能会稍微慢一点,但它不会将只有数字的行转换为nan。

这同样有效,并且可读性很强:

for column in df.select_dtypes("object").columns:
    df[column] = df[column].str.lower()

一个可能的缺点可能是
for
在列的子集上循环。

您可以只执行
df['my\u col']=df['my\u col'].astype(str).str.lower()
要强制所有内容都执行
str
,是否有理由混合
dtype
,因为这是没有性能的。。。我不确定。返回时,astype(str)不会将“Count”列中的所有整数转换为字符串吗?如果是这样的话,这难道不会阻止以后的算术运算吗?我应该在原来的问题中加上这个…谢谢!我同意这两种类型不应该混用。问题是这是用户输入的数据,很难阻止人们这样做!下次,我需要更好地限制用户输入。@user4896331在此之前,
pd。to_numeric
是你的朋友。如果您以前没有看到编辑,请查看我的答案。谢谢。另一个答案也很好,但这一个在应用小写字母之前对对象进行了测试,这正是我所寻找的。
>>> 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
df_lower=df.apply(lambda x: x.astype(str).str.lower() if(x.dtype == 'object') else x)
for column in df.select_dtypes("object").columns:
    df[column] = df[column].str.lower()