thêm tiền tố chuỗi vào mỗi giá trị trong cột chuỗi bằng Pandas


119

Tôi muốn nối một chuỗi vào đầu mỗi giá trị trong một cột đã nói của khung dữ liệu gấu trúc (một cách trang nhã). Tôi đã tìm ra cách thực hiện điều này và tôi hiện đang sử dụng:

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

Đây có vẻ là một việc không cần thiết phải làm - bạn có biết cách nào khác không (cách này cũng có thể thêm ký tự vào các hàng mà cột đó là 0 hoặc NaN)?

Trong trường hợp điều này vẫn chưa rõ ràng, tôi muốn chuyển sang:

    col 
1     a
2     0

thành:

       col 
1     stra
2     str0

Chính xác là bạn đang hỏi cái gì? xin vui lòng viết một lời giải thích về những gì mã của bạn làm / muốn nó đã làm
Ryan Saxe

1
Tôi nghĩ mã ví dụ làm rất rõ ràng đối với người dùng gấu trúc bình thường. Tôi đã thêm các ví dụ trường hợp sử dụng để thuận tiện cho bạn.
TheChymera

3
Mô tả của bạn hơi mâu thuẫn với mã của bạn. Chuyện gì xảy ra với != Falsedoanh nghiệp? Bạn muốn thêm strvào mọi giá trị hay chỉ một số?
BrenBarn

đến mọi giá trị, như được hiển thị trong khung dữ liệu mẫu của tôi.
TheChymera

1
Ví dụ của bạn vẫn còn một chút không rõ ràng, bạn có muốn một cái gì đó như thế df['col'] = 'str' + df['col'].astype(str)nào không?
Roman Pekar

Câu trả lời:


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

Thí dụ:

>>> 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
cảm ơn bạn. nếu quan tâm, các chỉ mục khung dữ liệu cũng hỗ trợ các thao tác chuỗi như vậy.
tagoma

2
Làm cách nào để làm điều này nếu các điều kiện phải được đáp ứng trước khi ghép nối?
acecabana

1
@tagoma, sau 4 năm, Có: nó cũng hỗ trợ các chỉ số khung dữ liệu. Bạn có thể tạo một cột mới và append với giá trị chỉ số như: df [ 'col'] = 'str' + df.index.astype (str)
Medwin

"astype (str)" có thể làm hỏng mã hóa nếu cuối cùng bạn đang cố gắng lưu vào một tệp.
Raein Hashemi

2
Khi tôi thử cách này cũng như bất kỳ cách tiếp cận nào khác, tôi nhận được SettingWithCopyWarning. Có cách nào để tránh nó?
Madan Ivan

13

Thay vào đó, bạn cũng có thể sử dụng applykết hợp với format(hoặc tốt hơn với f-string) mà tôi thấy dễ đọc hơn một chút nếu một ví dụ cũng muốn thêm hậu tố hoặc thao tác với chính phần tử:

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

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

điều này cũng mang lại đầu ra mong muốn:

    col
0  stra
1  str0

Nếu bạn đang sử dụng Python 3.6+, bạn cũng có thể sử dụng f-string:

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

sản lượng như nhau.

Phiên bản f-string gần như nhanh bằng giải pháp của @ 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)

formatTuy nhiên, sử dụng thực sự chậm hơn nhiều:

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

cùng một kết quả, nhưng chậm hơn ;-)
Philipp_Kats 13/09/18

1
@Philipp_Kats: Tôi đã thêm một số thời gian, cảm ơn vì đề xuất! Có vẻ như các chuỗi f cũng nhanh như vậy; formatthực sự hoạt động kém hơn. Bạn đã so sánh như thế nào?
Cleb

ồ hay! theo sự hiểu biết của tôi, .applyluôn luôn nhanh hoặc chậm hơn các hoạt động vectơ hóa "trực tiếp"; ngay cả khi chúng không chậm hơn, tôi muốn tránh chúng nếu có thể.
Philipp_Kats 13/09/18

@Philipp_Kats: Tôi đồng ý, tuy nhiên, trong trường hợp cụ thể này, tôi tìm thấy nó dễ đọc hơn khi tôi cũng thêm một hậu tố, làm điều gì đó với xbản thân vv, nhưng đó chỉ là một vấn đề của hương vị ... :)
Cleb

4

Bạn có thể sử dụng pandas.Series.map:

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

Nó sẽ áp dụng từ "str" ​​trước tất cả các giá trị của bạn.


3

Nếu bạn tải tệp bảng của mình bằng dtype=str
hoặc chuyển đổi loại cột thành chuỗi df['a'] = df['a'].astype(str)
thì bạn có thể sử dụng phương pháp như vậy:

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

Cách tiếp cận này cho phép thêm trước, nối thêm và chuỗi tập hợp con của df.
Hoạt động trên Pandas v0.23.4, v0.24.1. Không biết về các phiên bản trước.


0

Một giải pháp khác với .loc:

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

Điều này không nhanh như các giải pháp ở trên (chậm hơn> 1ms mỗi vòng lặp) nhưng có thể hữu ích trong trường hợp bạn cần thay đổi có điều kiện, như:

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

Tại sao .indexvào df[mask].index?
AMC

@AMC vì đối với .loc, bạn cần các chỉ số của khung dữ liệu. Nó có nghĩa là - df [mask] trả về khung dữ liệu phù hợp với điều kiện và df [mask] .index trả về các chỉ số của khung dữ liệu. Nhưng đúng là bạn cũng có thể làm tương tự với df.loc [(df ['col'] == 'a'), 'col'] hoặc df.loc [mask, 'col'].
Lukas

1
vì đối với .loc, bạn cần các chỉ số của khung dữ liệu. Nếu df.loc[mask]hoạt động, và nó có, thì điều đó .indexlà không cần thiết, phải không?
AMC

@AMC chính xác :). Tôi đã chỉnh sửa giải pháp. Cảm ơn bạn.
Lukas
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.