2017-10-29 25 views
12

Tôi có một khung dữ liệu 227x4 với tên quốc gia và giá trị số để làm sạch (wrangle?).Làm thế nào để thay thế 'chuỗi bất kỳ' bằng nan trong gấu trúc DataFrame bằng cách sử dụng mặt nạ boolean?

Dưới đây là một khái niệm trừu tượng của DataFrame:

import pandas as pd 
import random 
import string 
import numpy as np 
pdn = pd.DataFrame(["".join([random.choice(string.ascii_letters) for i in range(3)]) for j in range (6)], columns =['Country Name']) 
measures = pd.DataFrame(np.random.random_integers(10,size=(6,2)), columns=['Measure1','Measure2']) 
df = pdn.merge(measures, how= 'inner', left_index=True, right_index =True) 

df.iloc[4,1] = 'str' 
df.iloc[1,2] = 'stuff' 
print(df) 

    Country Name Measure1 Measure2 
0   tua  6  3 
1   MDK  3 stuff 
2   RJU  7  2 
3   WyB  7  8 
4   Nnr  str  3 
5   rVN  7  4 

Làm thế nào để thay thế các giá trị chuỗi với np.nan trong tất cả các cột mà không cần chạm tên nước?

tôi đã cố gắng sử dụng một mặt nạ boolean:

mask = df.loc[:,measures.columns].applymap(lambda x: isinstance(x, (int, float))).values 
print(mask) 

[[ True True] 
[ True False] 
[ True True] 
[ True True] 
[False True] 
[ True True]] 

# I thought the following would replace by default false with np.nan in place, but it didn't 
df.loc[:,measures.columns].where(mask, inplace=True) 
print(df) 

    Country Name Measure1 Measure2 
0   tua  6  3 
1   MDK  3 stuff 
2   RJU  7  2 
3   WyB  7  8 
4   Nnr  str  3 
5   rVN  7  4 


# this give a good output, unfortunately it's missing the country names 
print(df.loc[:,measures.columns].where(mask)) 

    Measure1 Measure2 
0  6  3 
1  3  NaN 
2  7  2 
3  7  8 
4  NaN  3 
5  7  4 

tôi đã xem xét một số câu hỏi liên quan đến mỏ ([1], [2], [3], [4], [5], [6], [7], [8]), nhưng không thể tìm thấy một đã trả lời sự quan tâm của tôi.

+0

"Một meta-câu hỏi, là nó bình thường mà tôi Tôi mất hơn 3 giờ để xây dựng một câu hỏi ở đây (bao gồm cả nghiên cứu)? " - Vâng. Thành công của [so] và toàn bộ mạng Stack Exchange được dựa trên chất lượng cao của nội dung, cả câu hỏi và câu trả lời. Bạn không thể ném cùng một câu hỏi chất lượng cao trong một vài phút. Cá nhân, tôi đặt nỗ lực cần thiết nhiều hơn vào thứ tự của ngày hơn giờ. Tôi chắc chắn đã dành cả ngày hoặc nhiều hơn cho một câu trả lời, và tôi hy vọng người yêu cầu phải dành ít nhất một đơn đặt hàng nhiều nỗ lực hơn, vì anh ta là người nhận được lợi ích. –

+0

Lưu ý phụ: các câu hỏi meta phải được hỏi trên [meta]. –

+0

@ JörgWMittag Tôi chỉ đếm thời gian để viết câu hỏi sau khi tôi đã tự mình cố gắng. Nếu tôi phải tính rằng nó sẽ là trong những ngày thực sự. Tôi sẽ đặt câu hỏi trong meta khi tôi có thêm vài giờ nữa trước mặt tôi. Tôi cảm thấy ngớ ngẩn mất quá nhiều thời gian để hỏi câu hỏi của tôi. Nhưng bây giờ tôi cảm thấy tốt hơn và chất lượng của câu trả lời là bằng chứng cho thấy nó cũng đáng để nỗ lực. Cảm ơn bạn! –

Trả lời

5

Gán chỉ cột quan tâm:

cols = ['Measure1','Measure2'] 
mask = df[cols].applymap(lambda x: isinstance(x, (int, float))) 

df[cols] = df[cols].where(mask) 
print (df) 
    Country Name Measure1 Measure2 
0   uFv  7  8 
1   vCr  5  NaN 
2   qPp  2  6 
3   QIC  10  10 
4   Suy  NaN  8 
5   eFS  6  4 

Một meta-câu hỏi, là nó bình thường mà tôi phải mất hơn 3 giờ để xây dựng một câu hỏi ở đây (bao gồm cả nghiên cứu)?

Theo ý kiến ​​của tôi, tạo câu hỏi hay là rất khó.

+0

Tôi thích bạn asnwer, nhưng tại sao 'df2 = df.loc [:, measure.columns]. Where (mặt nạ, inplace = True)' không làm thay thế? Trong khi 'df.loc [:, measure.columns] .where (mask)' in ra chính xác. –

+0

Vì 'inplace' luôn trả về' None', vì vậy 'df2' là None – jezrael

+0

Tôi đã chỉnh sửa câu hỏi .. Tôi không hiểu tại sao df.loc [:, measure.columns] .where (mask, inplace = True) không sửa đổi df? –

7
cols = ['Measure1','Measure2'] 
df[cols] = df[cols].applymap(lambda x: x if not isinstance(x, str) else np.nan) 

hoặc

df[cols] = df[cols].applymap(lambda x: np.nan if isinstance(x, str) else x) 

Kết quả:

In [22]: df 
Out[22]: 
    Country Name Measure1 Measure2 
0   nBl  10.0  9.0 
1   Ayp  8.0  NaN 
2   diz  4.0  1.0 
3   aad  7.0  3.0 
4   JYI  NaN  10.0 
5   BJO  9.0  8.0 
+1

Không phải là số không một giải pháp tốt? – Dark

+0

Nhưng tại sao phủ định 'x nếu không phải là isinstance (x, str)' thay vì 'x nếu isinstance (int, float) khác' np.nan'? –

+1

Điều đó sẽ thay thế tất cả các số bằng nan nếu bạn không cần phủ định rồi 'x: np.nan nếu isinstance (x, str) khác x' – Dark

5

Sử dụng số với các lỗi ép buộc tức là

cols = ['Measure1','Measure2'] 
df[cols] = df[cols].apply(pd.to_numeric,errors='coerce') 
 
Country Name Measure1 Measure2 
0   PuB  7.0  6.0 
1   JHq  2.0  NaN 
2   opE  4.0  3.0 
3   pxl  3.0  6.0 
4   ouP  NaN  4.0 
5   qZR  4.0  6.0 
+2

Tôi nghĩ chúng ta có thể loại bỏ 'lambda' trong trường hợp này:' df [cols] = df [cols] .apply (pd.to_numeric, errors = 'corece') ' – MaxU

+1

Cảm ơn bạn. Tôi đã có bữa ăn tối của tôi đến bây giờ. – Dark

+0

@Bharathshetty, câu trả lời của bạn quá tốt (nếu có thể). Tôi sẽ thực sự ép buộc chuỗi giá trị số nhưng điều này không rõ ràng với tôi khi tôi xây dựng câu hỏi. Trọng tâm của tôi là cách sử dụng mặt nạ boolean và tại sao tại chỗ không làm việc. –

Các vấn đề liên quan