2017-07-12 38 views
0

我有一個數據框由一個帶有日期對象的索引和一個填充了字符串的列「PSM」組成。這些字符串可以是各種類型或NaN。其中一種可能的格式是「5%」,「3%」,「%3」以及各種類似的格式。在數據框的有條件選擇的行中過濾數字

目標是過濾包含PSM中的%-sign的行,並僅替換值。作爲一個整數數量,以 「5%」 應更改爲5, 「%3」, 「3%」,以3等等

我已經試過各種事情:

  1. 使用for-loop遍歷行並在%上使用in進行過濾,然後嘗試使用int(filter(str.isdigit, string))更改該值,但是我無法將頭部圍繞如何實際更改x。

    for x in df.PSM: 
        if '%' in x: 
         do "int(filter(str.isdigit, string))" to x 
    
  2. 此外,for-loops總是讓我感到疑惑,我尋找更多pythonic方法來做到這一點。我發現了各種可能性,但無法讓其中一個人工作。 test['%' in test.PSM] = ?就是其中之一,但我不知道如何讓int(filter(str.isdigit, string))在右側工作。 類似df.loc['%' in df.PSM, int(filter(str.isdigit, df.PSM))]也不起作用。

所以我有兩個問題。 如何填充for循環的主體,以便像我想要的那樣執行? 而且,因爲我覺得必須有一個更優雅的方式,有什麼替代方法,可能更多的pythonic方法來過濾數字?

編輯與Exampledataframe:

data = ["% 5", "5%, ", "3%", "k52%"] 
col = ["PSM"] 
todays_date = datetime.datetime.now().date() 
index = pd.date_range(todays_date-datetime.timedelta(4), periods=4, freq='D') 
df = pd.DataFrame(data, index=index, columns=col) 

這看起來就像是:

  PSM 
2017-07-08 % 5 
2017-07-09 5%, 
2017-07-10 3% 
2017-07-11 k52% 

我希望它是這樣的:

  PSM 
2017-07-08 5 
2017-07-09 5 
2017-07-10 3 
2017-07-11 52 

回答

0

我認爲你可以使用str.contains與參數na=False布爾面膜,然後只使用str.extract號碼或str.replace/replace用於替換非數字空字符串:

data = ["% 5", "5%, ", "3%", "k52%", "aa", "ade3", np.nan] 
col = ["PSM"] 
todays_date = datetime.datetime.now().date() 
index = pd.date_range(todays_date-datetime.timedelta(4), periods=7, freq='D') 
df = pd.DataFrame(data, index=index, columns=col) 
print (df) 
      PSM 
2017-07-09 % 5 
2017-07-10 5%, 
2017-07-11 3% 
2017-07-12 k52% 
2017-07-13 aa 
2017-07-14 ade3 
2017-07-15 NaN 

mask = df['PSM'].str.contains('%', na=False) 
df.loc[mask, 'PSM'] = df.loc[mask, 'PSM'].str.extract('(\d+)', expand=False) 
print (df) 
      PSM 
2017-07-09  5 
2017-07-10  5 
2017-07-11  3 
2017-07-12 52 
2017-07-13 aa 
2017-07-14 ade3 
2017-07-15 NaN 

mask = df['PSM'].str.contains('%', na=False) 
df.loc[mask, 'PSM'] = df.loc[mask, 'PSM'].str.replace('(\D+)', '') 
print (df) 
      PSM 
2017-07-09  5 
2017-07-10  5 
2017-07-11  3 
2017-07-12 52 
2017-07-13 aa 
2017-07-14 ade3 
2017-07-15 NaN 

mask = df['PSM'].str.contains('%', na=False) 
df.loc[mask, 'PSM'] = df.loc[mask, 'PSM'].replace('(\D+)', '', regex=True) 
print (df) 
      PSM 
2017-07-09  5 
2017-07-10  5 
2017-07-11  3 
2017-07-12 52 
2017-07-13 aa 
2017-07-14 ade3 
2017-07-15 NaN 
0
import datetime 
import pandas as pd 
import re 

data = ["% 5", "5%, ", "3%", "k52%"] 
strp = re.compile(r'\d+') 
new_data = [] 
for item in data: 
    m = strp.search(item) 
    if m: 
     new_data.append(m.group(0)) 

col = ["PSM"] 
todays_date = datetime.datetime.now().date() 
index = pd.date_range(todays_date-datetime.timedelta(4), periods=4, freq='D') 
df = pd.DataFrame(new_data, index=index, columns=col) 
+0

我需要填寫什麼字符串? –

+0

它在你的問題中。問你自己。 – Rahul

+0

@ F.M .:嘗試編輯的解決方案。 – Rahul

0

你試過類似:

df.loc['%' in df.PSM,'PSM'] = df.loc['%' in df.PSM,'PSM'].replace('%','') 

編輯:

修正版本:

df.loc[df.PSM.str.contains('%'),'PSM'] = 
df.loc[df.PSM.str.contains('%'),'PSM'].str.replace(r'\D+',''‌​) 
+0

如果我嘗試這個,我得到一個錯誤。 'KeyError:'標籤[False]不在[index]中'不幸的是我不太明白你在做什麼,所以我不知道如何解決這個問題。你能解釋一下嗎? –

+0

如果沒有我可以重現的例子,很難對其進行測試 - df.loc [df.PSM.str.contains('%'),'PSM'] = df.loc [df.PSM.str.contains(' %'),'PSM']。replace('%','')?? – Greg

+0

我試圖使用.loc來使用布爾掩碼來分割你的df的一個子集,其中PSM字符串包含'%',然後用應用的替換這個切片.replace方法 – Greg

相關問題