2016-04-05 3 views
0

私は次のようなリストを持っています:li = ['ShortHair','LongHair','Medium Hair']Python - 別の列から部分文字列を取って列を更新する方法は?

col2とupdate col3から取得した場合、col2に上記の部分文字列が含まれているかどうかを確認します。そうでない場合は、そのままcol3を残してください。

 col1 col2    col3 
0  w I have    ShortHair 
1  x You Have   LongHair 
2  y I have no hair  W 
3  z Look !    Medium Hair 

EDIT:のストリングの複数の出現箇所がアレイ内に存在する場合、最初の値とフォームCOL2および更新COL3両方を削除取得する

 col1 col2    col3 
0  w I have ShortHair  U 
1  x LongHair You Have  V 
2  y I have no hair  W 
3  z Look Medium Hair!  L 

col2から部分文字列を削除できますが、col3は更新できません。私は試しました:

data[data.col2.str.contains('|'.join(li)),"col3"] = data["col2"].map(lambda x: re.findall('|'.join(li),x)[0]) 

これはエラーIndexError: list index out of rangeを与えます。

これを行うにはどうすればよいですか?

+0

"あなたは長髪か短髪ですか?" col3に含まれるものとその理由 – Alexander

+0

両方を削除してください。私は質問 – harshit

+0

@アレキサンダーを更新します私はこれが私が使用しているデータセットでは起こらないと確信しています。しかし、私の目的のために、最初の価値を取ることで十分です – harshit

答えて

1

サンプルデータフレームを作成します。

df = pd.DataFrame(
    {'col1': ['w', 'x', 'y', 'z'], 
    'col2': ['I have ShortHair', 'LongHair You Have', 'I have no hair', 'Look Medium Hair!'], 
    'col3': ['U', 'V', 'W', 'L']}) 

は、各行に一致するすべての単語を見つけるために、リスト内包してラムダ式を使用します。これは後で削除される一時的な列です。

df['matches'] = df.col2.apply(lambda sentence: [word for word in li if word in sentence]) 

一致する単語を含む行のマスクを作成します。マスクと.locを使用

mask = df.matches.apply(len) > 0 

、最初に一致した単語とcol3を更新します。

df.loc[mask, 'col3'] = df.loc[mask, 'matches'].str[0] 

col2からそれぞれ一致する単語を除去するreduceと共にラムダ式を使用する:

df.loc[mask, 'col2'] = (
    df.loc[mask, 'col2'].apply(lambda sentence: 
           reduce(lambda remaining_sentence, word: 
             remaining_sentence.replace(word, ''), li, sentence))) 

は一致単語の一時的な列を削除します。

del df['matches'] 

結果を確認します。

>>> df 
    col1   col2   col3 
0 w   I have  ShortHair 
1 x  You Have  LongHair 
2 y I have no hair   W 
3 z   Look ! Medium Hair 
関連する問題