2017-07-12 15 views
0

私は、日付オブジェクトを持つインデックスとストリングで埋められた列 "PSM"からなるデータフレームを持っています。これらの文字列は、さまざまな型またはNaNにすることができます。可能な形式の1つは、 "5%"、 "3%"、 "%3"などすべての種類の類似形式です。データフレームの条件付きで選択された行のフィルタ番号

目標は、PSMの%-signを含む行をフィルタリングし、 。。など、 "5%" は5に変更しなければならないので、整数として番号、 "%3" と3に "3%" と

は、私はいろいろなことを試してみました:

使用
  1. forループを使用して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な方法を探しました。私はいろいろな可能性を見出しましたが、そのうちの1人を働かせることはできませんでした test['%' in test.PSM] = ?のうちの1つですが、私は右端でint(filter(str.isdigit, string))を動作させる方法を知りません。 df.loc['%' in df.PSM, int(filter(str.isdigit, df.PSM))]のようなものも機能しませんでした。

私には2つの質問があります。 forループのボディを、私が望むように動作させる方法を教えてください。 そして、よりエレガントなやり方が必要だと思うのですが、その代わりに何が数字にフィルタをかけるためにもっと無愛想な方法がありますか? 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

私はあなたがboolean型マスク用のパラメータna=Falsestr.containsを使用して、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

'string'には何を記入する必要がありますか? –

+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

PSM文字列に '%'が含まれているブール値のマスクを使用して.locを使用してdfのサブセットをスライスし、適用された.replaceメソッドでこのスライスを置き換えようとしています – Greg

関連する問題