Pandas:将Series的数据类型更改为字符串

169

我使用Python 2.7中的Pandas 'ver 0.12.0',并且有一个如下的数据框:

df = pd.DataFrame({'id' : [123,512,'zhub1', 12354.3, 129, 753, 295, 610],
                    'colour': ['black', 'white','white','white',
                            'black', 'black', 'white', 'white'],
                    'shape': ['round', 'triangular', 'triangular','triangular','square',
                                        'triangular','round','triangular']
                    },  columns= ['id','colour', 'shape'])

id系列包含一些整数和字符串。它的默认 dtypeobject。我想将id的所有内容都转换为字符串。我尝试了astype(str),它生成了下面的输出。

df['id'].astype(str)
0    1
1    5
2    z
3    1
4    1
5    7
6    2
7    6

1) 如何将所有的id元素转换为字符串?

2) 我最终会使用id来对数据框进行索引。与使用整数索引相比,使用字符串索引在数据框中是否会减慢速度?


1
不确定为什么您会得到astype输出的那个结果,因为它在我这里运行良好,至少在版本0.13.1中是如此,也许0.12.0有一个错误?针对您的第二个问题,是的,由于字符串比较不会比整数比较更快,因此可能会慢一些,但我建议您首先进行性能分析,同时这也取决于数据量大小。 - EdChum
你已经设置好了列,对吧?df['id'] = df['id'].astype(str) - Andy Hayden
@Andy Hayden,是的,我做了这个约定,但我认为输出结果是意外的。 - Zhubarb
以何种方式出现了意外情况? - Andy Hayden
1
它只返回每个Series元素的第一个字符,就像我在问题中使用df['id'].astype(str)一样。 - Zhubarb
显示剩余2条评论
11个回答

223

最新的做法是:截至目前(v1.2.4),astype('str')astype(str)都不能转换数据类型。

根据文档,Series可以通过以下方式转换为字符串数据类型:

df['id'] = df['id'].astype("string")

df['id'] = pandas.Series(df['id'], dtype="string")

df['id'] = pandas.Series(df['id'], dtype=pandas.StringDtype)

1
当我尝试这个时,我得到了“数据类型"字符串"无法理解”的错误。 - thentangler
第一个解决方案在技术上可行,但会替换内容。将一行字符串复制到所有其他行。 第二个解决方案在技术上不起作用。第三个解决方案会抛出错误TypeError: Expected an instance of StringDtype, but got the class instead. Try instantiating 'dtype'.我会在加载数据时尝试指定数据类型。 - Simone
第三个解决方案缺少括号。以下是有效的代码: df['col'] = pandas.Series(df['col'], dtype=pd.StringDtype()) - Simone

125
你可以使用 apply 将所有 id 元素转换为 str
df.id.apply(str)

0        123
1        512
2      zhub1
3    12354.3
4        129
5        753
6        295
7        610

由 OP 编辑:

我认为这个问题与 Python 版本(2.7)有关,以下代码有效:

df['id'].astype(basestring)
0        123
1        512
2      zhub1
3    12354.3
4        129
5        753
6        295
7        610
Name: id, dtype: object

4
谢谢,我下次在电脑旁尝试并接受你的答案。你知道为什么astype(str)不起作用吗? - Zhubarb
2
@Zhubarb - 我刚试了一下,使用 df['id'].astype(str) 得到了相同的结果。 - Amit
4
我认为应该使用.astype('str')而不是.astype(str) - Alex Klibisz
2
@ErnestSKirubakaran - 请阅读前面的评论,尝试使用.astype('str') - Amit
1
我认为apply并不是将向量转换为字符串的矢量化方式。 - MMK
显示剩余4条评论

70
你必须像这样分配它:-
df['id']= df['id'].astype(str)

8

就我个人而言,以上方法都没有起作用。 真正有效的是:

new_str = [str(x) for x in old_obj][0]

是的,其他方法都没有改变任何东西。我知道它们本应该有效,但有些地方不对,所以我想这也是一个解决方案。 - Vengenzz Vicky

7

您可以使用:

df.loc[:,'id'] = df.loc[:, 'id'].astype(str)

这就是为什么他们推荐使用这个解决方案:Pandas文档 简而言之:
反映了一些答案:
df['id'] = df['id'].astype("string")

这个例子会出错,因为它会尝试将字符串转换为无法处理任何数字的StringArray
df['id']= df['id'].astype(str)

对我来说,这个解决方案会引发一些警告:

> SettingWithCopyWarning:  
> A value is trying to be set on a copy of a
> slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead

6

有两种可能性:


3

2

如果您想要动态地进行操作

df_obj = df.select_dtypes(include='object')
df[df_obj.columns] = df_obj.astype(str)

2

使用pandas字符串方法,例如df['id'].str.cat()


1
您的问题可以通过先将其转换为对象来轻松解决。在转换为对象后,只需使用 "astype" 将其转换为字符串即可。
obj = lambda x:x[1:]
df['id']=df['id'].apply(obj).astype('str')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接