2017-07-07 12 views
2

人間の名前(接頭辞、ファーストネーム、ミドルネーム、ラストネーム、サフィックス)の標準5列を含む大量のデータを処理しています。これらを別々の列に読み込み可能な名前としてマージしたいと思います。私が持っている問題は、空白の値を処理することです - 問題は間隔の問題を作成します。また、元の列は変更できません。私の現在のプロセスはちょっとばかげていると感じます(でもうまくいきます!)ので、より洗練されたソリューションを探しています。Pandasカラムで人間の名前を処理するためのより良い/より速い方法はありますか?

私の現在のコード:このソリューションで

def add_space_prefix(x): 
    x = str(x) 
    if len(x) > 0: 
     return x + ' ' 
    else: 
     return x 


def add_space_middle(x): 
    x = str(x) 
    if len(x) > 0: 
     return ' ' + x 
    else: 
     return x 


def add_space_suffix(x): 
    x = str(x) 
    if len(x) > 0: 
     return ', ' + x 
    else: 
     return x` 

df["middlename"] = 
df["middlename"].map(lambda x: add_space_middle(x)) 
df["prefix"] = df["prefix"].map(lambda x: add_space_prefix(x)) 
df["suffix"] = df["suffix"].map(lambda x: add_space_suffix(x)) 
df['fullname'] = df["prefix"] + df["firstname"] + df[ 
     "middlename"] + ' ' + df["lastname"] + df['suffix'] 

サンプルデータフレーム

prefix firstname middlename lastname suffix fullname 
0   Michael     Hobart  Jr.  Michael Jobart, Jr. 
1 Mr.  Alan     Lilt    Mr. Alan Lilt 
2   Jon   A.   Smith  III  Jon A. Smith, III 
3   Joe      Miller    Joe Miller 
4   Mika  Jennifer Shabosky   Mika Jennifer Shabosky 
5 Mrs. Angela     Calder    Mrs. Angela Calder 
6   Boris  Al   Bert  Esq. Boris Al Bert, Esq. 
7 Dr.  Natasha     Chorus    Dr. Natasha Chorus 
8   Bill     Gibbons    Bill Gibbons 
+0

完全な例を示してください。あなたのデータフレームはありません。小さな例を提供するのは非常に簡単です。 –

+0

空白と言うと、それはNaNか空文字列ですか? –

+0

空文字列の場合は空白です。 – whateveryousayiam

答えて

4

オプション1
' '.joinpd.Series.str
我々はスペースで行全体に加わります。これにより、文字列の先頭または末尾のスペース、または中央のスペースが2つ以上になることがあります。これは、文字列アクセサメソッドを連鎖させることで処理します。

df.assign(
    lastname=df.lastname + ',' 
).apply(' '.join, 1).str.replace('\s+', ' ').str.strip(' ,') 

0  Michael Hobart, Jr. 
1    Mr. Alan Lilt 
2   Jon A. Smith, III 
3    Joe Miller 
4 Mika Jennifer Shabosky 
5  Mrs. Angela Calder 
6  Boris Al Bert, Esq. 
7  Dr. Natasha Chorus 
8    Bill Gibbons 
dtype: object 

df['fullname'] = df.assign(
    lastname=df.lastname + ',' 
).apply(' '.join, 1).str.replace('\s+', ' ').str.strip(' ,') 
df 

    prefix firstname middlename lastname suffix    fullname 
0   Michael    Hobart Jr.  Michael Hobart, Jr. 
1 Mr.  Alan     Lilt     Mr. Alan Lilt 
2    Jon   A.  Smith III  Jon A. Smith, III 
3    Joe    Miller      Joe Miller 
4    Mika Jennifer Shabosky   Mika Jennifer Shabosky 
5 Mrs. Angela    Calder    Mrs. Angela Calder 
6   Boris   Al  Bert Esq.  Boris Al Bert, Esq. 
7 Dr. Natasha    Chorus    Dr. Natasha Chorus 
8    Bill    Gibbons     Bill Gibbons 

オプション2
リスト内包
このソリューションでは、我々は最初のソリューションと同じ活動を行うが、我々は一緒にして内の文字列操作をバンドル理解。

[re.sub(r'\s+', ' ', ' '.join(s)).strip(' ,') 
for s in df.assign(lastname=df.lastname + ',').values.tolist()] 

['Michael Hobart, Jr.', 
'Mr. Alan Lilt', 
'Jon A. Smith, III', 
'Joe Miller', 
'Mika Jennifer Shabosky', 
'Mrs. Angela Calder', 
'Boris Al Bert, Esq.', 
'Dr. Natasha Chorus', 
'Bill Gibbons'] 

df['fullname'] = [re.sub(r'\s+', ' ', ' '.join(s)).strip(' ,') 
        for s in df.assign(lastname=df.lastname + ',').values.tolist()] 
df 

    prefix firstname middlename lastname suffix    fullname 
0   Michael    Hobart Jr.  Michael Hobart, Jr. 
1 Mr.  Alan     Lilt     Mr. Alan Lilt 
2    Jon   A.  Smith III  Jon A. Smith, III 
3    Joe    Miller      Joe Miller 
4    Mika Jennifer Shabosky   Mika Jennifer Shabosky 
5 Mrs. Angela    Calder    Mrs. Angela Calder 
6   Boris   Al  Bert Esq.  Boris Al Bert, Esq. 
7 Dr. Natasha    Chorus    Dr. Natasha Chorus 
8    Bill    Gibbons     Bill Gibbons 

オプションは3
pd.replacepd.DataFrame.stack
この1つは、我々がnp.nan''空白を置き換えるという点で少し異なっているように、我々はnp.nanstackときar自然に落とされた。これにより、' 'との結合がより簡単になります。理解の範囲内束ねる

df.assign(
    lastname=df.lastname + ',' 
).replace('', np.nan).stack().groupby(level=0).apply(' '.join).str.strip(',') 

0  Michael Hobart, Jr. 
1    Mr. Alan Lilt 
2   Jon A. Smith, III 
3    Joe Miller 
4 Mika Jennifer Shabosky 
5  Mrs. Angela Calder 
6  Boris Al Bert, Esq. 
7  Dr. Natasha Chorus 
8    Bill Gibbons 
dtype: object 

df['fullname'] = df.assign(
    lastname=df.lastname + ',' 
).replace('', np.nan).stack().groupby(level=0).apply(' '.join).str.strip(',') 
df 

    prefix firstname middlename lastname suffix    fullname 
0   Michael    Hobart Jr.  Michael Hobart, Jr. 
1 Mr.  Alan     Lilt     Mr. Alan Lilt 
2    Jon   A.  Smith III  Jon A. Smith, III 
3    Joe    Miller      Joe Miller 
4    Mika Jennifer Shabosky   Mika Jennifer Shabosky 
5 Mrs. Angela    Calder    Mrs. Angela Calder 
6   Boris   Al  Bert Esq.  Boris Al Bert, Esq. 
7 Dr. Natasha    Chorus    Dr. Natasha Chorus 
8    Bill    Gibbons     Bill Gibbons 

タイミング
は最速です!

%timeit df.assign(fullname=df.replace('', np.nan).stack().groupby(level=0).apply(' '.join)) 
%timeit df.assign(fullname=df.apply(' '.join, 1).str.replace('\s+', ' ').str.strip()) 
%timeit df.assign(fullname=[re.sub(r'\s+', ' ', ' '.join(s)).strip() for s in df.values.tolist()]) 

100 loops, best of 3: 2.51 ms per loop 
1000 loops, best of 3: 979 µs per loop 
1000 loops, best of 3: 384 µs per loop 
+0

接尾辞の前のカンマはどうですか? (例えば、「ジョンA.スミス、III」対「ジョンA.スミスIII」)。私は男が接尾辞カンマを望んでいると思う。 – NickBraunagel

+0

ちょうどupvoteを作った;ありがとうございます。 – NickBraunagel

+0

@NickBraunagel喜んで私は助けることができます。 – piRSquared

関連する問題