Tách / cắt tất cả các chuỗi của khung dữ liệu


80

Đang xóa các giá trị của khung dữ liệu nhiều kiểu trong python / pandas, tôi muốn cắt bớt các chuỗi. Tôi hiện đang thực hiện theo hai hướng dẫn:

import pandas as pd

df = pd.DataFrame([['  a  ', 10], ['  c  ', 5]])

df.replace('^\s+', '', regex=True, inplace=True) #front
df.replace('\s+$', '', regex=True, inplace=True) #end

df.values

Điều này khá chậm, tôi có thể cải thiện điều gì?


1
df.replace(r'\s*(.*?)\s*', r'\1', regex=True)
MaxU

1
Đây là câu trả lời tốt nhất, chỉ cần đăng nhập vào up-phiếu câu trả lời bằng cách @MaxU
Linkon

Câu trả lời:


151

Bạn có thể sử dụng DataFrame.select_dtypesđể chọn stringcột và sau đó applyhoạt động str.strip.

Lưu ý: Các giá trị không thể typesgiống dictshoặc lists, bởi vì chúng dtypesobject.

df_obj = df.select_dtypes(['object'])
print (df_obj)
0    a  
1    c  

df[df_obj.columns] = df_obj.apply(lambda x: x.str.strip())
print (df)

   0   1
0  a  10
1  c   5

Nhưng nếu chỉ có một vài cột, hãy sử dụng str.strip:

df[0] = df[0].str.strip()

1
Và SettingWithCopyWarning nên bị bỏ qua trong trường hợp này như đã giải thích stackoverflow.com/questions/20625582/…
Harvey

70

Bắn tiền

Đây là một phiên bản nhỏ gọn của việc sử dụng applymapvới biểu thức lambda đơn giản để stripchỉ gọi khi giá trị thuộc loại chuỗi:

df.applymap(lambda x: x.strip() if isinstance(x, str) else x)

Đầy đủ ví dụ

Một ví dụ đầy đủ hơn:

import pandas as pd


def trim_all_columns(df):
    """
    Trim whitespace from ends of each value across all series in dataframe
    """
    trim_strings = lambda x: x.strip() if isinstance(x, str) else x
    return df.applymap(trim_strings)


# simple example of trimming whitespace from data elements
df = pd.DataFrame([['  a  ', 10], ['  c  ', 5]])
df = trim_all_columns(df)
print(df)


>>>
   0   1
0  a  10
1  c   5

Ví dụ làm việc

Đây là một ví dụ hoạt động được lưu trữ bởi trinket: https://trinket.io/python3/e6ab7fb4ab


1
Xin chào @DaleKube ... Tôi vừa thử điều này mới trên một máy mới chỉ để kiểm tra độ tỉnh táo và tôi nhận được kết quả tương tự như đã đăng trong câu trả lời. Bạn có thể xác nhận xem bạn đang sử dụng Python2 hay Python3? Tôi chỉ sử dụng Python3 những ngày này, nhưng có lẽ đó có thể là một yếu tố. Nếu vậy, tôi sẽ ghi chú điều đó trong câu trả lời đã đăng của tôi nếu bạn có thể xác nhận. Cảm ơn!
Jonathan B.

1
Tôi đã xóa bình luận của mình. Tôi đã tìm thấy một lỗi trong mã của mình và tôi có thể xác nhận rằng nó hiện hoạt động như một sự quyến rũ. FYI, tôi đang sử dụng Python 3. Xin lỗi vì sự cố này.
Dale Kube

bạn nên sử dụng type(x) == str, khôngtype(x) is str
fjsj

@fjsj Cảm ơn bạn đã thúc đẩy. Tôi đã cập nhật ví dụ bằng cách sử dụng ưu tiên hướng dẫn PEP8 isinstance(x, str).
Jonathan B.

10

Bạn co thể thử:

df[0] = df[0].str.strip()

hoặc cụ thể hơn cho tất cả các cột chuỗi

non_numeric_columns = list(set(df.columns)-set(df._get_numeric_data().columns))
df[non_numeric_columns] = df[non_numeric_columns].apply(lambda x : str(x).strip())

9

Nếu bạn thực sự muốn sử dụng regex, thì

>>> df.replace('(^\s+|\s+$)', '', regex=True, inplace=True)
>>> df
   0   1
0  a  10
1  c   5

Nhưng sẽ nhanh hơn nếu làm như thế này:

>>> df[0] = df[0].str.strip()

5

Bạn có thể sử dụng applychức năng của Seriesđối tượng:

>>> df = pd.DataFrame([['  a  ', 10], ['  c  ', 5]])
>>> df[0][0]
'  a  '
>>> df[0] = df[0].apply(lambda x: x.strip())
>>> df[0][0]
'a'

Lưu ý cách sử dụng stripchứ không phải cái regexnào nhanh hơn nhiều

Một tùy chọn khác - sử dụng applychức năng của đối tượng DataFrame:

>>> df = pd.DataFrame([['  a  ', 10], ['  c  ', 5]])
>>> df.apply(lambda x: x.apply(lambda y: y.strip() if type(y) == type('') else y), axis=0)

   0   1
0  a  10
1  c   5

1
df[0] = df[0].str.strip()- sẽ, có lẽ hầu hết, hãy nhanh hơn trên DFS lớn
MaxU

-1
def trim(x):
    if x.dtype == object:
        x = x.str.split(' ').str[0]
    return(x)

df = df.apply(trim)

1
Bạn có thể giải thích những gì chức năng đang làm xin vui lòng?
CJ Dennis

Ví dụ, tôi gặp phải dữ liệu như thế này trong công việc hàng ngày của tôi: 가나다 봻 phần bên trái để trống là những gì tôi muốn, phần bên phải là rác. hàm trim trích xuất những gì tôi muốn từ dữ liệu thô.
hyunwoo jeong

Đã phản đối vì điều này không cắt chuỗi, nó sẽ xóa mọi thứ theo sau khoảng trắng đầu tiên. Đây không phải là hành vi được yêu cầu trong câu hỏi và đưa ra những tác dụng phụ mà người đọc có thể không mong đợi. Hơn nữa, các tác dụng phụ có thể không rõ ràng ngay lập tức. Nếu bạn đang cố gắng cắt bỏ một cột Họ, bạn có thể nghĩ rằng điều này đang hoạt động như dự định vì hầu hết mọi người không có nhiều họ và dấu cách ở cuối có thể bị loại bỏ. Sau đó, một người Bồ Đào Nha có hai Họ tham gia vào trang web của bạn và mã cắt bỏ Họ của họ, chỉ để lại Họ của họ.
scottclowe
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.