3

NLP とテキスト マイニングで簡単な計算を行うために pandas を調べていましたが、その方法をよく理解できませんでした。

人の名前と性別を関連付ける次のデータ フレームがあるとします。

import pandas
people = {'name': ['John Doe', 'Mary Poppins', 'Jane Doe', 'John Cusack'], 'gender': ['M', 'F', 'F', 'M']}
df = pandas.DataFrame(people)

私がしたいすべての行について:

  1. ファーストネームを決める
  2. 人の名前に由来する 3-shingles (単語に含まれる 3 文字のシーケンス) のリストを決定する
  3. 帯状疱疹ごとに、その帯状疱疹を名前に含む男性と女性の数を決定します。

目標は、これをデータセットとして使用して、与えられた名前がおそらく男性か女性かを判断できる分類子をトレーニングすることです。

最初の 2 つの操作は非常に簡単です。

def shingles(word, n = 3):
    return [word[i:i + n] for i in range(len(word) - n + 1)]

df['firstname'] = df.name.map(lambda x : x.split()[0])
df['shingles'] = df.firstname.map(shingles)

結果は次のとおりです。

> print df


  gender          name firstname        shingles
0      M      John Doe      John  ['joh', 'ohn']
1      F  Mary Poppins      Mary  ['mar', 'ary']
2      F      Jane Doe      Jane  ['jan', 'ane']
3      M   John Cusack      John  ['joh', 'ohn']

ここで、次のステップは、次のようなものを含む必要がある、性別とシングルの 2 つの列を持つ新しいデータ フレームを作成することによって実行する必要があります。

   gender      shingle 
0       M          joh
1       M          ohn
2       F          mar
3       F          ary
(...)

そして、帯状疱疹と性別でグループ化できました。理想的には、結果は次のようになります。

   shingle    num_males  num_females 
0      joh            2            0 
1      ohn            2            0 
2      mar            0            1 
3      ary            0            1
(...)

shingles各行がシングルのリストで見つかった各値に対して 1 つずつ、複数の行を生成する方法で多値列を拡張する簡単な方法はありますか?

また、私groupbyが列の場合、列shingleの可能な値ごとにカウントされた異なる列を作成するのはどれほど簡単genderですか?


後半部分は理解できました。例として、それぞれの男性と女性の数を計算するにはfirstname:

 def countMaleFemale(df): 
     return pandas.Series({'males': df.gender[df.gender == 'M'].count(), 
                           'females': df.gender[df.gender == 'F'].count()})

grouped = df.groupby('first name')

その後:

print grouped.apply(countMaleFemale)

            females  males
first name                
Jane              1      0
John              0      2
Mary              1      0
4

2 に答える 2

7

この方法は、かなり一般化する必要があります。

In [100]: df
Out[100]:
  gender          name firstname    shingles
0      M      John Doe      John  [Joh, ohn]
1      F  Mary Poppins      Mary  [Mar, ary]
2      F      Jane Doe      Jane  [Jan, ane]
3      M   John Cusack      John  [Joh, ohn]

最初に、すべてのエントリがシングルである「拡張」シリーズを作成します。ここで、シリーズのインデックスは multiindex であり、最初のレベルはシングルの位置を表し、2 番目のレベルは元の DF のインデックスを表します。

In [103]: s = df.shingles.apply(lambda x: pandas.Series(x)).unstack();
Out[103]:
0  0    Joh
   1    Mar
   2    Jan
   3    Joh
1  0    ohn
   1    ary
   2    ane
   3    ohn

次に、作成したシリーズを元のデータフレームに結合できます。インデックスをリセットして、シングルの位置レベルを下げる必要があります。結果のシリーズには、元のインデックスと各シングルのエントリがあります。これを元のデータフレームにマージすると、次が生成されます。

In [106]: df2 = df.join(pandas.DataFrame(s.reset_index(level=0, drop=True))); df2
Out[106]:
  gender          name firstname    shingles    0
0      M      John Doe      John  [Joh, ohn]  Joh
0      M      John Doe      John  [Joh, ohn]  ohn
1      F  Mary Poppins      Mary  [Mar, ary]  Mar
1      F  Mary Poppins      Mary  [Mar, ary]  ary
2      F      Jane Doe      Jane  [Jan, ane]  Jan
2      F      Jane Doe      Jane  [Jan, ane]  ane
3      M   John Cusack      John  [Joh, ohn]  Joh
3      M   John Cusack      John  [Joh, ohn]  ohn

最後に、Gender で groupby 操作を実行し、返されたシリーズをアンスタックして、NaN をゼロで埋めることができます。

In [124]: df2.groupby(0, sort=False)['gender'].value_counts().unstack().fillna(0)
Out[124]:
     F  M
0
Joh  0  2
ohn  0  2
Mar  1  0
ary  1  0
Jan  1  0
ane  1  0
于 2013-03-07T17:20:39.167 に答える
2

作成時に拡張バージョンを作成する方が簡単な場合がありますshinglesこの質問は、この種の拡張を行うために groupby を使用する方法を示しています。「名」列を作成した後にできることの例を次に示します。

def shingles(table, n = 3):
    word = table['first name'].irow(0)
    shingles = [word[i:i + n] for i in range(len(word) - n + 1)]
    cols = {col: table[col].irow(0) for col in table.columns}
    cols['shingle'] = shingles
    return pandas.DataFrame(cols)

>>> df.groupby('name', group_keys=False).apply(shingles)
  first name gender          name shingle
0       Jane      F      Jane Doe     Jan
1       Jane      F      Jane Doe     ane
0       John      M   John Cusack     Joh
1       John      M   John Cusack     ohn
0       John      M      John Doe     Joh
1       John      M      John Doe     ohn
0       Mary      F  Mary Poppins     Mar
1       Mary      F  Mary Poppins     ary

(名前が重複している場合に備えて、ここでは名前ではなく名前でグループ化しましたが、完全な名前は一意であると想定しています。)

そこから、好きなようにグループ化して数えることができるはずです。

于 2013-03-06T18:45:46.673 に答える