2017-07-14 3 views
0

私はNFLシナリオの大きなデータセットを持っていますが、説明のために2つの観測値のリストに減らしてみましょう。このように:数値を文字列に変換するためのラムダの適用

data = [[scenario1],[scenario2]] 

ここでは、データ・セットは、で構成されてものです:

data[0][0] 
>>"It is second down and 3. The ball is on your opponent's 5 yardline. There is 3 seconds left in the fourth quarter. You are down by 3 points." 

data[1][0] 
>>"It is first down and 10. The ball is on your 20 yardline. There is 7 minutes left in the third quarter. You are down by 10 points." 

私はこのような文字列形式でデータを持つ任意のモデルを構築することはできません。ですから、これらのシナリオを定量的な値として新しい列(または必要ならフィーチャー)に再コード化したいと思います。

down = 0 
yards = 0 
yardline = 0 
seconds = 0 
quarter = 0 
points = 0 

data = [[scenario1, down, yards, yardline, seconds, quarter, points], [scenario2, yards, yardline, seconds, quarter, points]] 

は今トリッキーな部分ですが、私は、シナリオ列からの情報から新しい列を移入する必要があり、いくつかの方法:私は、私は最初のデータフレームが離れて二乗し得るべきであると思いました。トリッキーなのは、たとえば、第2文で「相手の」という単語が存在する場合、それはヤードラインの番号が何であれ100を計算する必要があるということです。上記の scenario1変数では、100-5 = 95である必要があります。

最初はすべての数字を分けて単語を捨てるべきだと思ったが、上で指摘したように、実際に量的な値を正しく割り当てるにはいくつかの単語が実際に必要です。私はこのような微妙なことでラムダを作ったことはありません。あるいは、ラムダは正しい方法ではないでしょうか?私は任意/すべての提案に開放されています。補強のための

は、ここで私が入力した場合scenario1から(見たいものです。

data[0][1:] 
>>2,3,95,3,4,-3 

はあなたに

答えて

1

ありがとうラムダは、あなたがここに行きたいつもりだ方法ではありませんPythonの。 reモジュールは、私は[[scenario, <scenario_data>], ...]のようなあなたのデータを格納することは少し奇妙です見つけるが、データを追加するために、個人的にあなたの友人:)

from re import search 

def getScenarioData(scenario): 
    data = [] 

    ordinals_to_nums = {'first':1, 'second':2, 'third':3, 'fourth':4} 
    numerals_to_nums = { 
     'zero':0, 'one':1, 'two':2, 'three':3, 'four':4, 
     'five':5, 'six':6, 'seven':7, 'eight':8, 'nine':9 
    } 

    # Downs 
    match = search('(first|second|third|fourth) down and', scenario) 
    if match: 
     raw_downs = match.group(1) 
     downs = ordinals_to_nums[raw_downs] 
     data.append(downs) 

    # Yards 
    match = search('down and (\S+)\.', scenario) 
    if match: 
     raw_yards = match.group(1) 
     data.append(int(raw_yards)) 

    # Yardline 
    match = search("(oponent's)? (\S+) yardline", scenario) 
    if match: 
     raw_yardline = match.groups() 
     yardline = 100-int(raw_yardline[1]) if raw_yardline[0] else int(raw_yardline[1]) 
     data.append(yardline) 

    # Seconds 
    match = search('(\S+) (seconds|minutes) left', scenario) 
    if match: 
     raw_secs = match.groups() 
     multiplier = 1 if raw_secs[1] == 'seconds' else 60 
     data.append(int(raw_secs[0]) * multiplier) 

    # Quarter 
    match = search('(\S+) quarter', scenario) 
    if match: 
     raw_quarter = match.group(1) 
     quarter = ordinals_to_nums[raw_quarter] 
     data.append(quarter) 

    # Points 
    match = search('(up|down) by (\S+) points', scenario) 
    if match: 
     raw_points = match.groups() 
     if raw_points: 
      polarity = 1 if raw_points[0] == 'up' else -1 
      points = int(raw_points[1]) * polarity 
     else: 
      points = 0 
     data.append(points) 

    return data 

ですdata[0][3]のような使用してインデックスは、今から1,2ヶ月を混乱得ることができるので、私は辞書のリストを使用することをお勧めし

for s in data: 
    s.extend(getScenarioData(s[0])) 

:各シナリオに

def getScenarioData(scenario): 
    # instead of data = [] 
    data = {'scenario':scenario} 

    # instead of data.append(downs) 
    data['downs'] = downs 

    ... 

scenarios = ['...', '...'] 
data = [getScenarioData(s) for s in scenarios] 

はEDIT:あなたが値を取得したいです鍵が見つからない場合dictsから、NoneからKeyErrorgetため、デフォルト値を上げ防ぐためにgetメソッドを使用します。

for s in data: 
    print(s.get('quarter')) 
+0

うわー、それは非常に便利です!私は別のデータフレームを試し、どのパンが良く見えるか見てみましょう。私はそれをあなたの方法でdictsのリストで見始めている。 –

+0

私は助けることができる嬉しい:) – Nelson

+0

私はそれが動作すると確信していますが、エラーは "なしタイプ"のオブジェクトは属性を持っていない:グループ。データを調べたところ、「あなたは3歳になった」のように、いくつかのシナリオが本当にシンプルであることに気付きました。これに 'try' /' except'を使うべきですか?または0またはnaにデフォルトする別の方法がありますか?私はあなたのコードのいくつかが 'if'を持っていることに気付きました、おそらく私はすべてのコードでそれをタグ付けするべきでしょうか? –

関連する問題