Làm cách nào để xóa ký hiệu đô la khỏi chuỗi trong python?

Tôi đang tìm cách xóa các ký hiệu đô la khỏi toàn bộ khung dữ liệu python pandas. Nó tương tự như bài đăng này

Xóa toàn bộ nhân vật

Tuy nhiên, tôi đang tìm cách xóa ký hiệu đô la không hoạt động. Tôi tin rằng đó là do regex coi ký hiệu đô la là phần cuối của chuỗi, nhưng tôi không chắc phải làm gì với nó. Đây là những gì tôi đã tạo ra cho đến nay

Một ngày nọ, tôi đang sử dụng gấu trúc để xóa một số dữ liệu Excel lộn xộn bao gồm hàng nghìn hàng giá trị tiền tệ được định dạng không nhất quán. Khi tôi cố gắng dọn dẹp nó, tôi nhận ra rằng nó phức tạp hơn tôi nghĩ lúc đầu một chút. Thật trùng hợp, vài ngày sau, tôi đã theo dõi một chủ đề trên twitter làm sáng tỏ vấn đề mà tôi đang gặp phải. Bài viết này tóm tắt kinh nghiệm của tôi và mô tả cách dọn sạch các trường tiền tệ lộn xộn và chuyển đổi chúng thành một giá trị số để phân tích thêm. Các khái niệm được minh họa ở đây cũng có thể áp dụng cho các loại nhiệm vụ dọn dẹp dữ liệu gấu trúc khác

Dữ liệu

Dưới đây là chế độ xem đơn giản về dữ liệu Excel lộn xộn

Trong ví dụ này, dữ liệu là sự kết hợp của các giá trị được gắn nhãn tiền tệ và không được gắn nhãn tiền tệ. Đối với một ví dụ nhỏ như thế này, bạn có thể muốn dọn dẹp nó ở tệp nguồn. Tuy nhiên, khi bạn có một tập dữ liệu lớn [với dữ liệu được nhập thủ công], bạn sẽ không có lựa chọn nào khác ngoài việc bắt đầu với dữ liệu lộn xộn và dọn dẹp nó trong pandas

Trước khi tiếp tục, có thể hữu ích khi xem lại bài viết trước của tôi về các loại dữ liệu. Trên thực tế, làm việc với bài viết này đã thúc đẩy tôi sửa đổi bài viết gốc của mình để làm rõ các loại dữ liệu được lưu trữ trong cột

df['Sales'].astype['float']
0

Hãy đọc trong dữ liệu

import pandas as pd

df_orig = pd.read_excel['sales_cleanup.xlsx']
df = df_orig.copy[]

Khách hàngBán hàng0Jones Brothers5001Beta Corp$1.000. 002Globex Corp300. 13Acme$750. 014Initech3005Hooli250

Tôi đã đọc dữ liệu và tạo một bản sao của dữ liệu đó để giữ bản gốc

Một trong những điều đầu tiên tôi làm khi tải dữ liệu là kiểm tra các loại

df.dtypes

Customer    object
Sales       object
dtype: object

Không có gì đáng ngạc nhiên khi cột

df['Sales'].astype['float']
1 được lưu trữ dưới dạng một đối tượng. '$' và ',' là quà tặng đã chết mà cột
df['Sales'].astype['float']
1 không phải là cột số. Nhiều khả năng chúng tôi muốn thực hiện một số phép toán trên cột, vì vậy, hãy thử chuyển đổi nó thành float

Trong tập dữ liệu thế giới thực, bạn có thể không nhanh chóng nhận ra rằng có các giá trị không phải là số trong cột. Trong tập dữ liệu của tôi, cách tiếp cận đầu tiên của tôi là cố gắng sử dụng

df['Sales'].astype['float']
3

df['Sales'].astype['float']

________số 8

Truy nguyên bao gồm một

df['Sales'].astype['float']
4 và cho thấy rằng nó không thể chuyển đổi 1.000 đô la. 00 chuỗi thành float. Được. Điều đó sẽ dễ dàng dọn dẹp

Hãy thử loại bỏ '$' và ',' bằng cách sử dụng

df['Sales'].astype['float']
5

import pandas as pd

df_orig = pd.read_excel['sales_cleanup.xlsx']
df = df_orig.copy[]
1

import pandas as pd

df_orig = pd.read_excel['sales_cleanup.xlsx']
df = df_orig.copy[]
2

Hừm. Đó không phải là những gì tôi mong đợi. Vì lý do nào đó, các giá trị chuỗi đã được dọn sạch nhưng các giá trị khác được chuyển thành

df['Sales'].astype['float']
6. Đó là một vấn đề lớn

Thành thật mà nói, đây chính xác là những gì đã xảy ra với tôi và tôi đã dành nhiều thời gian hơn đáng lẽ để cố gắng tìm ra điều gì đang xảy ra. Cuối cùng tôi đã hiểu ra và sẽ giải quyết vấn đề ở đây để bạn có thể học hỏi từ những khó khăn của tôi

Chuỗi twitter từ Ted Petrou và nhận xét từ Matt Harrison đã tóm tắt vấn đề của tôi và xác định một số đoạn trích hữu ích về gấu trúc mà tôi sẽ mô tả bên dưới

Về cơ bản, tôi giả định rằng một cột

df['Sales'].astype['float']
0 chứa tất cả các chuỗi. Trên thực tế, một cột đối tượng có thể chứa hỗn hợp nhiều loại

Hãy cùng xem các loại trong tập dữ liệu này

import pandas as pd

df_orig = pd.read_excel['sales_cleanup.xlsx']
df = df_orig.copy[]
5

import pandas as pd

df_orig = pd.read_excel['sales_cleanup.xlsx']
df = df_orig.copy[]
6

ahhh. Điều này độc đáo cho thấy vấn đề. Mã

df['Sales'].astype['float']
8 chạy hàm
df['Sales'].astype['float']
9 trên từng giá trị trong cột. Như bạn có thể thấy, một số giá trị là số float, một số là số nguyên và một số là chuỗi. Nhìn chung, cột
---------------------------------------------------------------------------
ValueError                                Traceback [most recent call last]
 in 
----> 1 df['Sales'].astype['float']

.....
ValueError: could not convert string to float: '$1,000.00'
0 là một đối tượng

Đây là hai mẹo hữu ích, tôi đang thêm vào hộp công cụ của mình [nhờ Ted và Matt] để phát hiện những vấn đề này sớm hơn trong quá trình phân tích của tôi

Đầu tiên, chúng ta có thể thêm một cột được định dạng hiển thị từng loại

df.dtypes
0

CustomerSalesSales_Type0Jones Brothers500int1Beta Corp$1.000. 00str2Globex Corp300. 1float3Acme$750. 01str4Initech300int5Hooli250int

Hoặc, đây là một cách nhỏ gọn hơn để kiểm tra các loại dữ liệu trong một cột bằng cách sử dụng

---------------------------------------------------------------------------
ValueError                                Traceback [most recent call last]
 in 
----> 1 df['Sales'].astype['float']

.....
ValueError: could not convert string to float: '$1,000.00'
1

df.dtypes
0

df.dtypes
1

Tôi chắc chắn sẽ sử dụng điều này trong phân tích hàng ngày của mình khi xử lý các loại dữ liệu hỗn hợp

Khắc phục sự cố

Để minh họa vấn đề và xây dựng giải pháp;

Đầu tiên, tạo một biến số và chuỗi

df.dtypes
2

df.dtypes
3

Ví dụ này tương tự với dữ liệu của chúng ta ở chỗ chúng ta có một chuỗi và một số nguyên. Nếu chúng tôi muốn xóa chuỗi để loại bỏ các ký tự thừa và chuyển đổi thành float

df.dtypes
4

df.dtypes
5

Được. Đó là những gì chúng tôi muốn

Điều gì xảy ra nếu chúng ta thử điều tương tự với số nguyên của mình?

df.dtypes
6

df.dtypes
7

Có vấn đề. Chúng tôi gặp lỗi khi cố gắng sử dụng các hàm chuỗi trên số nguyên

Khi pandas cố gắng thực hiện một cách tiếp cận tương tự bằng cách sử dụng bộ truy cập

---------------------------------------------------------------------------
ValueError                                Traceback [most recent call last]
 in 
----> 1 df['Sales'].astype['float']

.....
ValueError: could not convert string to float: '$1,000.00'
2, nó sẽ trả về một
df['Sales'].astype['float']
6 thay vì một lỗi. Đó là lý do tại sao các giá trị số được chuyển đổi thành
df['Sales'].astype['float']
6

Giải pháp là kiểm tra xem giá trị có phải là một chuỗi không, sau đó thử xóa nó. Nếu không, hãy tránh gọi các hàm chuỗi trên một số

Cách tiếp cận đầu tiên là viết một chức năng tùy chỉnh và sử dụng

---------------------------------------------------------------------------
ValueError                                Traceback [most recent call last]
 in 
----> 1 df['Sales'].astype['float']

.....
ValueError: could not convert string to float: '$1,000.00'
5

df.dtypes
8

Hàm này sẽ kiểm tra xem giá trị được cung cấp có phải là một chuỗi hay không và nếu có, sẽ xóa tất cả các ký tự mà chúng ta không cần. Nếu đó không phải là một chuỗi thì nó sẽ trả về giá trị ban đầu

Đây là cách chúng tôi gọi nó và chuyển đổi kết quả thành float. Tôi cũng hiển thị cột có các loại

df.dtypes
9

Khách hàngBán hàngSales_Type0Jones Brothers500. 00float1Beta Corp1000. 00float2Globex Corp300. 10float3Acme750. 01float4Initech300. 00float5Hooli250. 00phao

Chúng tôi cũng có thể kiểm tra

---------------------------------------------------------------------------
ValueError                                Traceback [most recent call last]
 in 
----> 1 df['Sales'].astype['float']

.....
ValueError: could not convert string to float: '$1,000.00'
6

df.dtypes

Customer    object
Sales       object
dtype: object
1

Hoặc nhìn vào

---------------------------------------------------------------------------
ValueError                                Traceback [most recent call last]
 in 
----> 1 df['Sales'].astype['float']

.....
ValueError: could not convert string to float: '$1,000.00'
7

df.dtypes
0

Customer    object
Sales       object
dtype: object
3

Được. Đó là tất cả có vẻ tốt. Chúng tôi có thể tiếp tục với bất kỳ hàm toán học nào chúng tôi cần áp dụng trên cột bán hàng

Trước khi kết thúc, tôi sẽ trình bày một ví dụ cuối cùng về cách thực hiện điều này bằng cách sử dụng hàm lambda

Customer    object
Sales       object
dtype: object
4

Hàm lambda là một cách nhỏ gọn hơn để làm sạch và chuyển đổi giá trị nhưng có thể khó hiểu hơn đối với người dùng mới. Cá nhân tôi thích một chức năng tùy chỉnh trong trường hợp này. Đặc biệt nếu bạn phải dọn dẹp nhiều cột

Lời cảnh báo cuối cùng mà tôi có là bạn vẫn cần hiểu dữ liệu của mình trước khi thực hiện việc dọn dẹp này. Tôi giả định rằng tất cả các giá trị bán hàng đều tính bằng đô la. Đó có thể là một giả định hợp lệ hoặc không

Nếu có các giá trị tiền tệ hỗn hợp ở đây, thì bạn sẽ cần phát triển một phương pháp làm sạch phức tạp hơn để chuyển đổi sang định dạng số nhất quán. Pyjanitor có chức năng có thể thực hiện chuyển đổi tiền tệ và có thể là một giải pháp hữu ích cho các vấn đề phức tạp hơn

Các giải pháp thay thế

Sau khi tôi xuất bản bài báo ban đầu, tôi đã nhận được một số gợi ý chu đáo về các cách khác để giải quyết vấn đề. Đề xuất đầu tiên là sử dụng biểu thức chính quy để xóa các ký tự không phải là số khỏi chuỗi

Customer    object
Sales       object
dtype: object
5

Cách tiếp cận này sử dụng pandas Series. thay thế. Nó trông rất giống với phương pháp thay thế chuỗi nhưng mã này thực sự xử lý các giá trị không phải chuỗi một cách phù hợp

Biểu thức thông thường đôi khi có thể khó hiểu. Tuy nhiên, cái này đơn giản nên tôi sẽ không ngần ngại sử dụng cái này trong một ứng dụng trong thế giới thực. Cảm ơn Serg đã chỉ ra điều này

Giải pháp thay thế khác được cả Iain Dinwoodie và Serg chỉ ra là chuyển đổi cột thành chuỗi và sử dụng an toàn

---------------------------------------------------------------------------
ValueError                                Traceback [most recent call last]
 in 
----> 1 df['Sales'].astype['float']

.....
ValueError: could not convert string to float: '$1,000.00'
8

Trước tiên, chúng tôi đọc dữ liệu và sử dụng đối số

---------------------------------------------------------------------------
ValueError                                Traceback [most recent call last]
 in 
----> 1 df['Sales'].astype['float']

.....
ValueError: could not convert string to float: '$1,000.00'
0 thành
import pandas as pd

df_orig = pd.read_excel['sales_cleanup.xlsx']
df = df_orig.copy[]
10 để buộc cột dữ liệu ban đầu được lưu trữ dưới dạng chuỗi

Customer    object
Sales       object
dtype: object
6

Chúng tôi có thể kiểm tra nhanh

df.dtypes
0

Customer    object
Sales       object
dtype: object
8

Sau đó áp dụng quy trình dọn dẹp của chúng tôi và chuyển đổi loại

Customer    object
Sales       object
dtype: object
9

Vì tất cả các giá trị được lưu trữ dưới dạng chuỗi, mã thay thế hoạt động như mong đợi và không chuyển đổi sai một số giá trị thành

import pandas as pd

df_orig = pd.read_excel['sales_cleanup.xlsx']
df = df_orig.copy[]
11

Bản tóm tắt

Kiểu dữ liệu pandas

df['Sales'].astype['float']
0 thường được sử dụng để lưu trữ các chuỗi. Tuy nhiên, bạn không thể cho rằng các kiểu dữ liệu trong một cột pandas
import pandas as pd

df_orig = pd.read_excel['sales_cleanup.xlsx']
df = df_orig.copy[]
13 sẽ là các chuỗi. Điều này có thể đặc biệt gây nhầm lẫn khi tải dữ liệu tiền tệ lộn xộn có thể bao gồm các giá trị số có ký hiệu cũng như số nguyên và số float

Rất có thể các phương pháp làm sạch ngây thơ sẽ vô tình chuyển đổi các giá trị số thành

df['Sales'].astype['float']
6. Bài viết này cho biết cách sử dụng một số thủ thuật pandas để xác định các loại riêng lẻ trong một cột đối tượng, làm sạch chúng và chuyển đổi chúng thành giá trị số thích hợp

Tôi hy vọng bạn đã tìm thấy điều này hữu ích. Nếu bạn có bất kỳ mẹo hoặc câu hỏi nào khác, hãy cho tôi biết trong phần nhận xét

Chủ Đề