Pandas kullanarak bir dize sütunundaki her değere bir dize öneki ekleyin


119

Bir pandalar veri çerçevesinin söz konusu sütunundaki her değerin başlangıcına bir dize eklemek istiyorum (zarifçe). Bunu nasıl yapacağımı zaten buldum ve şu anda kullanıyorum:

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

Bu, yapılması gereken cehennemsiz bir şey gibi görünüyor - başka bir yol biliyor musunuz (bu, o sütunun 0 veya NaN olduğu satırlara karakteri de ekleyebilir)?

Bu henüz net değilse, açmak isterim:

    col 
1     a
2     0

içine:

       col 
1     stra
2     str0

tam olarak ne soruyorsun? lütfen kodunuzun ne yaptığı / yapmasını dilediğiniz hakkında bir açıklama yazın
Ryan Saxe

1
Örnek kodun ne yaptığını ortalama bir panda kullanıcısı için çok açık olduğunu düşündüm. Size kolaylık sağlamak için kullanım durumu örnekleri ekledim.
TheChymera

3
Açıklamanız kodunuzla bir şekilde çelişiyor. != Falseİşin nesi var ? strHer değere mi yoksa sadece bazılarına mı eklemek istiyorsunuz ?
BrenBarn

örnek veri çerçevelerimde gösterildiği gibi her değere.
TheChymera

1
Örneğiniz hala biraz belirsiz, gibi bir şey df['col'] = 'str' + df['col'].astype(str)mi istiyorsunuz ?
Roman Pekar

Yanıtlar:


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

Misal:

>>> 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
teşekkür ederim. ilgi alanına göre, veri çerçevesi dizinleri de bu tür dizi işlemlerini destekler.
tagoma

2
Birleştirmeden önce koşulların karşılanması gerekiyorsa bunu nasıl yapabilirim?
acecabana

1
@tagoma, 4 yıl sonra, Evet: Dataframe dizinlerini de destekliyor. Yeni bir sütun oluşturabilir ve indeks değerine şu şekilde ekleyebilirsiniz: df ['col'] = 'str' + df.index.astype (str)
MEdwin

Sonunda bir dosyaya kaydetmeye çalışıyorsanız "astype (str)" kodlamayı bozabilir.
Raein Hashemi

2
Bunu ve başka bir yaklaşımı denediğimde, bir SettingWithCopyWarning alıyorum. Bundan kaçınmanın bir yolu var mı?
Madan Ivan

13

Alternatif olarak, applybirleşik format(veya daha iyisi f-dizeleri ile) kullanabilirsiniz, eğer biri ayrıca bir sonek eklemek veya öğenin kendisini değiştirmek isterse biraz daha okunaklı buluyorum:

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

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

bu da istenen çıktıyı verir:

    col
0  stra
1  str0

Python 3.6+ kullanıyorsanız, f dizelerini de kullanabilirsiniz:

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

aynı çıktıyı verir.

F-string sürümü neredeyse @ RomanPekar'ın çözümü (python 3.6.4) kadar hızlıdır:

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)

formatAncak kullanmak gerçekten çok daha yavaştır:

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

sonuç aynı, ama çok daha yavaş ;-)
Philipp_Kats

1
@Philipp_Kats: Bazı zamanlamalar ekledim, öneri için teşekkürler! Görünüşe göre f-dizeleri neredeyse aynı hızda; formatgerçekten daha kötü performans gösterir. Nasıl karşılaştırdın?
Cleb

Oh iyi! benim anlayışıma göre .apply, her zaman "doğrudan" vektörleştirilmiş işlemlerden daha hızlı veya daha yavaştır; Yavaş olmasalar bile, mümkün olduğunca onlardan kaçınmayı tercih ederim.
Philipp_Kats

@Philipp_Kats: Katılıyorum, ancak bu özel durumda, bir sonek eklediğimde, xkendisiyle bir şeyler yaptığımda vs. daha okunaklı buluyorum , ama bu sadece bir zevk meselesi ... :)
Cleb

4

Pandas.Series.map'i kullanabilirsiniz:

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

Tüm değerlerinden önce "str" ​​kelimesini uygulayacaktır.


3

Tablo dosyanızı dtype=str
sütun tipiyle yüklerseniz veya dizeye dönüştürürseniz df['a'] = df['a'].astype(str)
, bu yaklaşımı kullanabilirsiniz:

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

Bu yaklaşım dizesinin başına, sonuna ve alt kümesine izin verir df.
Pandas v0.23.4, v0.24.1 üzerinde çalışır. Önceki sürümleri bilmiyorum.


0

.Loc ile başka bir çözüm:

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

Bu, yukarıdaki çözümler kadar hızlı değildir (döngü başına> 1 ms daha yavaş), ancak aşağıdaki gibi koşullu değişikliğe ihtiyaç duyduğunuzda yararlı olabilir:

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

Neden .indexgiriş df[mask].index?
AMC

@AMC çünkü .loc için veri çerçevesinin dizinlerine ihtiyacınız var. Bunun anlamı - df [mask] koşulla eşleşen veri çerçevesi döndürür ve df [maske] .index, veri çerçevesinin dizinlerini döndürür. Ancak aynısını df.loc [(df ['col'] == 'a'), 'col'] veya df.loc [mask, 'col'] ile de yapabileceğiniz doğrudur.
Lukas

1
çünkü .loc için veri çerçevesinin dizinlerine ihtiyacınız var. Eğer df.loc[mask]çalışır ve o, o zaman gelmez .indexgereksiz olduğunu, doğru mu?
AMC

@AMC tam olarak :). Çözümü düzenledim. Teşekkür ederim.
Lukas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.