2016-11-08 17 views
0

パスを表す文字列を持つデータフレーム列があります。私は別の列の値としてそのパスのいくつかを使用したいと思います。列値のデータフレーム文字列の解析

文字列は次のように似ていると'Image Location'

C:\Users\Chris H\Desktop\20161017HCT116\Day 4\D2\Image9.tif 
C:\Users\Chris H\Desktop\20161017HCT116\Day 4\D6\Image7.tif 
C:\Users\Chris H\Desktop\20161017HCT116\Day 4\D7\Image3.tif 
... 
C:\Users\Chris H\Desktop\20161017HCT116\Day 6\D2\Image7.tif 
C:\Users\Chris H\Desktop\20161017HCT116\Day 6\D2\Image1.tif 
C:\Users\Chris H\Desktop\20161017HCT116\Day 6\D2\Image6.tif 
C:\Users\Chris H\Desktop\20161017HCT116\Day 6\D3\Image4.tif 
C:\Users\Chris H\Desktop\20161017HCT116\Day 6\D3\Image9.tif 
... 
C:\Users\Chris H\Desktop\20161017HCT116\Day 8\D1\Image4.tif 
C:\Users\Chris H\Desktop\20161017HCT116\Day 8\D1\Image9.tif 
C:\Users\Chris H\Desktop\20161017HCT116\Day 8\D1\Image3.tif 
C:\Users\Chris H\Desktop\20161017HCT116\Day 8\D2\Image7.tif 
C:\Users\Chris H\Desktop\20161017HCT116\Day 8\D2\Image1.tif 
C:\Users\Chris H\Desktop\20161017HCT116\Day 8\D2\Image6.tif 

の欄に今、私は次のことをやっている:

df['Interval'] = df['Image Location'].str.split('\\').apply(lambda x: x[5]) 
df['Device'] = df['Image Location'].str.split('\\').apply(lambda x: x[6]) 

これは明らかにあまり変更しないようにパスが必要IntervalとDeviceの値を見つけるために\の数を数えているからです。

これを行うためのより堅牢な方法があるのだろうかと思います。例えば、Day #D#のようなパターンを見つけることができます。

答えて

1

私はSeries.str.extract()メソッドを使用します:Intervalとそれに対応Device:このソリューションで

In [40]: df[['Interval','Device']] = \ 
      df['Image Location'].str.extract(r'([^\\]+)\\([^\\]+)\\[^\\]+$', expand=True) 

In [41]: df 
Out[41]: 
               Image Location Interval Device 
0 C:\Users\Chris H\Desktop\20161017HCT116\Day 4\D2\Image9.tif Day 4  D2 
1 C:\Users\Chris H\Desktop\20161017HCT116\Day 4\D6\Image7.tif Day 4  D6 
2 C:\Users\Chris H\Desktop\20161017HCT116\Day 4\D7\Image3.tif Day 4  D7 
3 C:\Users\Chris H\Desktop\20161017HCT116\Day 6\D2\Image7.tif Day 6  D2 
4 C:\Users\Chris H\Desktop\20161017HCT116\Day 6\D2\Image1.tif Day 6  D2 
5 C:\Users\Chris H\Desktop\20161017HCT116\Day 6\D2\Image6.tif Day 6  D2 
6 C:\Users\Chris H\Desktop\20161017HCT116\Day 6\D3\Image4.tif Day 6  D3 
7 C:\Users\Chris H\Desktop\20161017HCT116\Day 6\D3\Image9.tif Day 6  D3 
8 C:\Users\Chris H\Desktop\20161017HCT116\Day 8\D1\Image4.tif Day 8  D1 
9 C:\Users\Chris H\Desktop\20161017HCT116\Day 8\D1\Image9.tif Day 8  D1 
10 C:\Users\Chris H\Desktop\20161017HCT116\Day 8\D1\Image3.tif Day 8  D1 
11 C:\Users\Chris H\Desktop\20161017HCT116\Day 8\D2\Image7.tif Day 8  D2 
12 C:\Users\Chris H\Desktop\20161017HCT116\Day 8\D2\Image1.tif Day 8  D2 
13 C:\Users\Chris H\Desktop\20161017HCT116\Day 8\D2\Image6.tif Day 8  D2 

Here is parsed and explained RegEx

正規表現は、あなたの最後の2つのパスの部分(ディレクトリ)が常にあることを前提としています。あなたは\年代の数に依存したくない場合は

あなたがこのような何かを行うことができ、パス

+0

非常に興味深い解決策。 – agf1997

1

の先頭にありますどのように多くの\(バックスラッシュ)は重要ではありません:

df['Image Location'].map(lambda x: re.findall(r'(?<=Day)[0-9]+', x)).map(lambda x: np.nan if not x else x[0]) 
df['Image Location'].map(lambda x: re.findall(r'(?<=D)[0-9]+', x)).map(lambda x: np.nan if not x else x[0]) 

これは、最初のサブストリングを見つけるDay(またはD)と、すぐにそのに続く数字を返します。したがって、文字列に他のパターンがないと仮定すると、Dのようなすべてのパターンを任意の桁数で取得するためです。

更新: Series.str.extractが@MaxUとして推奨されているようです。 ここに行く:

df['Image Location'].str.extract('[Day ]([0-9]+)') 
df['Image Location'].str.extract('[D]([0-9]+)') 
+0

これは私が元々考えていた方向だった。私はどのソリューションが良いか分からない、これは@MaxUからのものだ。これは、\ Day#と\ D#の間のいくつかのパス変更に対して堅牢であるようだ。 'C:\ Users \ Chris H \ Desktop \ 20161017HCT116 \ Day 8 \ run 1 \ D2 \ Image6.tif'になりますが、これは起こりそうにありません。 Maxのソリューションは、C:\ Users \ Chris H \ Desktop \ 20161017HCT116 \ 48 hr \ D2 \ Image6.tif'の日数から時間に変化する堅牢性を備えています。 – agf1997