Pandasを使用して文字列列の各値に文字列プレフィックスを追加する


119

パンダデータフレームの上記の列の各値の先頭に(エレガントに)文字列を追加したいと思います。私はすでにこれをどのように行うかを考え出し、現在使用しています:

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

これは、やらなければならないエレガントなことの1つの地獄のようです-他の方法を知っていますか?

これがまだ不明な場合は、次のように変更します。

    col 
1     a
2     0

に:

       col 
1     stra
2     str0

あなたは正確に何を求めていますか?あなたのコードが何をするか/それがしたいことについての説明を書いてください
Ryan Saxe

1
サンプルのコードが何をするかは、平均的なパンダのユーザーには非常に明確であると思いました。参考までに、使用例を追加しました。
TheChymera 2013年

3
あなたの説明はあなたのコードと多少矛盾しています。何アップしている!= Falseビジネス?strすべての値に追加しますか、それとも一部のみに追加しますか?
BrenBarn 2013年

私の例のデータフレームに示すように、すべての値に。
TheChymera 2013年

1
あなたの例はまだ少し不明瞭ですが、あなたは何かをしたいdf['col'] = 'str' + df['col'].astype(str)ですか?
Roman Pekar 2013年

回答:


223
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
ありがとうございました。興味があれば、データフレームインデックスもそのような文字列操作をサポートします。
タゴマ2017

2
連結前に条件を満たす必要がある場合、どうすればよいですか?
acecabana

1
@ tagoma、4年後、はい:データフレームインデックスもサポートします。新しい列を作成し、次のようにインデックス値に追加できます。df ['col'] = 'str' + df.index.astype(str)
MEdwin

最後にファイルに保存しようとすると、「astype(str)」がエンコーディングを台無しにする可能性があります。
Raein Hashemi、

2
これと他のアプローチを試すと、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-stringsも使用できます。

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

同じ出力が得られます。

f-stringバージョンは、@ 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)

同じ結果ですが、
かなり

1
@Philipp_Kats:私はいくつかのタイミングを追加しました、提案に感謝します!f-stringsはほとんど同じように高速です。format確かにパフォーマンスが悪い。どのように比較しましたか?
クレブ2018

いいね!私の理解で.applyは、「直接的な」ベクトル化された操作と同じくらい速いか遅いかのどちらかです。それらが遅くなくても、私は可能な限りそれらを避けることを好みます。
Philipp_Kats 2018

@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

.locにはデータフレームのインデックスが必要なため、@ AMC。つまり、df [mask]は条件に一致するデータフレームを返し、df [mask] .indexはデータフレームのインデックスを返します。しかし、df.loc [(df ['col'] == 'a')、 'col']またはdf.loc [mask、 'col']でも同じことができるのは事実です。
ルーカス

1
.locにはデータフレームのインデックスが必要だからです。動作する場合、df.loc[mask]動作しますが、それ.indexは不要ですよね?
AMC

@AMC正確に:)。ソリューションを編集しました。ありがとうございました。
Lukas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.