pandasでgroupbyしたオブジェクトの中身をみよう

groupbyオブジェクトをprintする方法

groupbyしたあとは「DataFrameGroupBy」オブジェクトになる。その中身をみるには以下のような方法がある

 df = pd.DataFrame([{"a" : 1,"b" : 2 , "c" : 3 },{"a" : 2 , "b" : 3, "c" : 5},{"a" : 1 , "b" : 9, "c" : 5} ] ,index=['1','2','3'])
# df
   a  b  c
1  1  2  3
2  2  3  5
3  1  9  5
 df2 = df.groupby('a')
# df2
<pandas.core.groupby.generic.DataFrameGroupBy object at 0x114688588>
# df2.first()
   b  c
a
1  2  3
2  3  5
# df2.last()
   b  c
a
1  9  5
2  3  5
>>> for key, item in df2:
...     print(df2.get_group(key), "\n\n")
...
   b  c
1  2  3
3  9  5


   b  c

※ pandas インデックスオブジェクトは重複値をサポートしています。groupby操作でグループキーとして一意ではないインデックスを使用した場合、同じインデックス値に対するすべての値が1つのグループ内にあるとみなされるため、集約関数の出力には一意なインデックス値のみが含まれることになります。

Group by: split-apply-combine — pandas 1.1.3 documentation

pandasでDataFrameで差分をとる

以下のようなDataframeを考えよう。

df = pd.DataFrame([{"a" : 1,"b" : 2 , "c" : 3 },{"a" : 2 , "b" : 3, "c" : 5},{"a" : 1 , "b" : 9, "c" : 5} ] ,index=['1','2','3'])
# df
   a  b  c
1  1  2  3
2  2  3  5
3  1  9  5

このとき、a列の値ごとに差分をとりたい場合を考える。すでにindexされてる行で区別して差分をとることは簡単だが、a列の値ごとに差分を求めたい場合は少しばかり工夫がいる

ここで仮に普通にdf.diffしてしまうと、1行ごとに差分をとってしまいうまくかない。

df.diff()
     a    b    c
1  NaN  NaN  NaN
2  1.0  1.0  2.0
3 -1.0  6.0  0.0

そこでgroupbyをかませる。

df.groupby('a').diff()
     b    c
1  NaN  NaN
2  NaN  NaN
3  7.0  2.0

provider.iamRoleStatementsでLambdaの権限を追加

LambdaのIAM Roleの設定

Serverless frameworkのLambda関数のIAM Roleの設定を行う。 設定は設定ファイルserverless.ymlで行う。

デフォルトIAM Role

デフォルトでは、1つのIAM Roleはサービス*1内のすべてのLambda関数で共有されます。また、デフォルトでは、Lambda関数はCloudWatchログの作成と書き込みの権限を持っている。VPC設定が提供されている場合、VPCリソースと通信するためにデフォルトのAWS AWSLambdaVPCAccessExecutionRoleが関連付けられる。

このサービス全体のロールに特定の権利を追加するには、生成されたポリシーにマージされるステートメントをprovider.iamRoleStatementsで定義する。これらのステートメントは CloudFormation テンプレートにマージされるので、Join、Ref、その他の CloudFormation メソッドや機能を使用することができる。

service: new-service

provider:
  name: aws
  iamRoleStatements:
    - Effect: 'Allow'
      Action:
        - 's3:ListBucket'
      Resource:
        Fn::Join:
          - ''
          - - 'arn:aws:s3:::'
            - Ref: ServerlessDeploymentBucket
    - Effect: 'Allow'
      Action:
        - 's3:PutObject'
      Resource:
        Fn::Join:
          - ''
          - - 'arn:aws:s3:::'
            - Ref: ServerlessDeploymentBucket
            - '/*'

*1:Serverlessはサービスという単位で実行環境を作る

「serverless create」でテンプレからのserverless framework入門

serverless frameworkのテンプレ機能を使って気軽に入門

serverless create --template aws-python3 --name hello-world

このコマンドを実行後ファイルは以下のようになる

.gitignore
handler.py
serverless.yml

serverless frameworkを設定する : AWS編

インストール

以下のコマンドでグローバルインストール

sudo npm install -g serverless

Serverless frameworkの設定

serverless config credentials --provider aws --key <ACCESS KEY ID> --secret <SECRET KEY>

クレデンシャルファイルにキー/シークレットを保存しておけば、各コマンドでプロファイルを指定することで、Serverlessコマンドで以下のように使い分けれる。

serverless deploy --aws-profile serverless

プロファイルだけでなく、regionを環境変数にエクスポートすることも可能

export AWS_PROFILE="serverless" && export AWS_REGION=eu-west-1

serverless frameworkでpython packageのバンドルを楽々に

serverless frameworkのpython packageバンドリングプラグイン: serverless-python-requirements

serverless-python-requirementsとはrequirements.txtの依存関係を自動的にバンドルし、PYTHONPATHで利用できるようにするためのServerless v1.xプラグイン

インストール

sls plugin install -n serverless-python-requirements

Serverless Python Requirements

これにより、プロジェクトの package.json と serverless.yml の plugins セクションにプラグインが自動的に追加される。 基本的な使用方法はこれだけです! sls デプロイを実行すると、requirements.txt や Pipfile で指定した python の依存関係がプラグインにバンドルされる。

より詳しくは以下を参照

How to Handle your Python packaging in Lambda with Serverless plugins

もしあなたがMacを使っているのであれば、brewでインストールしたpythonを使う際の注意点を参照のこと。

Serverless Python Requirements

ロスコンパイル

ロスコンパイルしたい場合、Dockerとdocker-lambdaイメージを使うことで、非Linux OS上で可能。 docker を使用できるようにするには、serverless.yml に以下を追加する。

custom:
  pythonRequirements:
    dockerizePip: true