使用熊猫将字符串前缀添加到字符串列中的每个值


118

我想在熊猫数据帧的所述列中的每个值的开头附加一个字符串(优雅)。我已经弄清楚该如何做,目前正在使用:

df.ix[(df['col'] != False), 'col'] = 'str'+df[(df['col'] != False), 'col']

这似乎是一件微不足道的事情-您是否知道其他任何方式(可能还会将该字符添加到该列为0或NaN的行中)?

如果还不清楚,我想转一下:

    col 
1     a
2     0

变成:

       col 
1     stra
2     str0

你到底在问什么 请写上你的代码做什么解释/希望它做
瑞恩萨克森

1
我认为示例代码对普通的熊猫用户来说非常清楚。为了方便起见,我添加了用例示例。
TheChymera 2013年

3
您的描述与您的代码有些矛盾。什么与高达!= False公司吗?您要添加str每个值还是仅添加一些值?
BrenBarn

如我的示例数据框所示。
TheChymera

1
您的示例仍然不清楚,您想要类似的东西df['col'] = 'str' + df['col'].astype(str)吗?
Roman Pekar

Answers:


222
df['col'] = 'str' + df['col'].astype(str)

例:

>>> df = pd.DataFrame({'col':['a',0]})
>>> df
  col
0   a
1   0
>>> df['col'] = 'str' + df['col'].astype(str)
>>> df
    col
0  stra
1  str0

1
谢谢。如果感兴趣的话,数据帧索引也支持这种字符串操作。
塔戈马

2
如果必须在连接之前满足条件,该怎么办?
acecabana

1
@ tagoma,4年后,是的:它也支持数据框索引。您可以创建一个新列并将其附加到索引值上,如下所示:df ['col'] ='str'+ df.index.astype(str)
MEdwin

如果最后尝试保存到文件,则“ astype(str)”可能会破坏编码。
Raein Hashemi

1
当我尝试此方法以及其他任何方法时,都会看到SettingWithCopyWarning。有办法避免吗?
Madan Ivan

13

另外,您也可以使用apply组合format(或f字符串更好),如果例如还想添加后缀或操纵元素本身,我会觉得可读性更高:

df = pd.DataFrame({'col':['a', 0]})

df['col'] = df['col'].apply(lambda x: "{}{}".format('str', x))

这也会产生所需的输出:

    col
0  stra
1  str0

如果您使用的是Python 3.6+,则还可以使用f字符串:

df['col'] = df['col'].apply(lambda x: f"str{x}")

产生相同的输出。

f字符串版本几乎与@RomanPekar的解决方案(python 3.6.4)一样快:

df = pd.DataFrame({'col':['a', 0]*200000})

%timeit df['col'].apply(lambda x: f"str{x}")
117 ms ± 451 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit 'str' + df['col'].astype(str)
112 ms ± 1.04 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

format但是,使用的确确实要慢得多:

%timeit df['col'].apply(lambda x: "{}{}".format('str', x))
185 ms ± 1.07 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

同样的结果,但是速度更慢;-)
Philipp_Kats

1
@Philipp_Kats:我添加了一些时间,感谢您的建议!看来f弦几乎一样快。format确实表现较差。您如何比较?
克莱布(Cleb)

不错哦!以我的理解,.apply它总是比“直接”矢量化操作快或慢。即使它们并不慢,我还是希望尽可能避免它们。
Philipp_Kats

@Philipp_Kats:我同意,但是,在这种特殊情况下,当我还添加一个后缀,对x自身进行一些操作等时,我发现它更具可读性,但这只是一个口味问题... :)
Cleb

4

您可以使用pandas.Series.map:

df['col'].map('str{}'.format)

它将在所有值之前加上“ str”一词。


3

如果使用加载表文件dtype=str
或将列类型转换为字符串,df['a'] = df['a'].astype(str)
则可以使用以下方法:

df['a']= 'col' + df['a'].str[:]

这种方法允许使用的前缀,追加和子集字符串df
适用于Pandas v0.23.4,v0.24.1。不了解较早的版本。


0

.loc的另一种解决方案:

df = pd.DataFrame({'col': ['a', 0]})
df.loc[df.index, 'col'] = 'string' + df['col'].astype(str)

这没有上述解决方案快(每个循环慢1ms以上),但在需要条件更改时可能有用,例如:

mask = (df['col'] == 0)
df.loc[mask, 'col'] = 'string' + df['col'].astype(str)

为什么.indexdf[mask].index
AMC

@AMC,因为对于.loc,您需要数据帧的索引。这意味着-df [mask]返回符合条件的数据帧,而df [mask] .index返回该数据帧的索引。但是,确实可以使用df.loc [(df ['col'] =='a'),'col']或df.loc [mask,'col']进行相同操作。
卢卡斯

1
因为对于.loc,您需要数据帧的索引。如果df.loc[mask]有效,而且确实有效,那么.index多余的,对吧?
AMC

@AMC完全是:)。我已经编辑了解决方案。谢谢。
卢卡斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.