質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

538閲覧

pd.json_normalizeの結果をlen(df)した後、再度dfしcsvとしたい

msy47

総合スコア26

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2022/12/23 01:00

編集2022/12/23 03:20

前提

LambdaにてPythonを使用しvmanageへAPIを利用して
結果を取得し、取得したデータの加工を想定しています。

その際、APIで受信した結果をカウントし、再度データ構造化し
csvに変換しようと考えております。

その際結果がjsonが返ってくるため
内部の要素をカウントしたのち、最初のAPI結果と
リストとカウントを一覧化したいと考えております。

その際カウントとリストをどのように一覧化するか
どのようにコードを書いてよいかわからず。
ご助言をいただきたくおもいます。

実現したいこと

ここに実現したいことを箇条書きで書いてください。

  • 最初に実行したAPIリストと、pd.json_normalizeでカウントした結果を一覧化したい

ソース
#df①
print(df)

deviceId system-ip bfdSessionsUP bfdSessions
10.0.0.1 10.1.0.1 7.0 7
10.0.0.2 10.2.0.2 8.0 8

#df②
print(df)
inside-local-addr vrf-name ・・・ application-type inside-global-addr
10.9.0.1 -gloal- ・・・ 0 10.10.0.1
10.9.0.2 -gloal- ・・・ 0 10.10.0.2
[1 row x 17 columns]
2 ←#df③: print(len(df))

inside-local-addr vrf-name ・・・ application-type inside-global-addr
10.10.0.1 -gloal- ・・・ 0 10.11.0.1
10.10.0.2 -gloal- ・・・ 0 10.11.0.2
10.10.0.3 -gloal- ・・・ 0 10.11.0.3
[1 row x 17 columns]
3 ←#df③: print(len(df))

出力予定
deviceId system-ip bfdSessionsUP bfdSessions TunnnelCount(※df③の結果)
10.0.0.1 10.1.0.1 7.0 7 2
10.0.0.2 10.2.0.2 8.0 8 3

発生している問題・エラーメッセージ

melianさんの指摘により、カラムがないことが原因

"errorMessage" : "/None of [Index(["system-ip", "host-name", "device-model"], dtype = object`)] are in the [columns]/""

該当のソースコード

Lambda(Python)

1 2 3import json 4import boto3 5import csv 6import numpy as np 7import pandas as pd 8 9import requests 10import os 11import urllib3 12from datetime import datetime 13urllib3.disable_warnings(urlib3.exceptions.InsecureRequests.InsecureRequestWarning) 14 15def lambda_handler(event, context): 16 s3 = boto3.resource(`s3`) 17 bucket_name _ os.environ.get(`S3_BUCKET`) 18 vmange_info_df = pd.read_csv(vnamage_info) 19 20 device_info = "tmp/device_info.csv" 21 bucket.download_file(os.environ.get(`CSV_DEVICE_INFO`), device_info) 22 device_info_df = pd.read.csv(device_info) 23 24 ipsec_tunnel_df = get_request(vmanage_info_df) 25 26 def get_request(vmanage_info_df): 27 api_datalist = [] 28 for row in vmanage_info_df.itertuples(): 29 vmanage_host = row[1] 30 vmanage_port = row[2] 31 vmanage_username = row[3] 32 vmanage_password = row[4] 33 34 base_url = `https://%s:%s`%(vmanage_host, vmanage_port) 35 36 login_action = `/j_security_check` 37 38 login_data = {`j_username` : vmanage_username, `j_password` : vmanage_password} 39 40 login_url = base_url + login_action 41 42 session = requests.session() 43 44 login_response = session.post(url=login_url, data=login_data, verify=False) 45 if login_token.status_code = 200: 46 if b`<html>` in login_token.content: 47 print("Login token Failed") 48 exit(1) 49 50 session.headers[`X-XSRF-TOKEN`] = login_token.content 51 52 53 device_url = base_url + `/dataservice/device` 54 55 df = pd.json_normalize(json_data["data"]) 56 df = df[(df["device-type"] == "vedge") & (df["reachability"] == "reachable")] 57 58#df① 59print(df) 60 61 for data in df.itertuples() 62 deviceid = data[1] 63 nat_translation_url = base_url + `/dataservice/devie/ip/nat/translation?deviceId=` + deviceid 64 nat_translation_list = sessin.get(url=nat_translation_url, verify=False) 65 if nat_translation_list.status_code == 200: 66 json_data = nat_translation_list.json = () 67 else: 68 print(nat_translation_list.status_code) 69 70 df = pd.json_normalize(json_data["data"] 71 #df② 72 print(df) 73 74   #df③ 75 print(len(df)) 76 77   #一時的にコメントアウト:indexは存在しない 78   #df = df[["system-ip", "host-name", "device-model"]] 79   #df[Tunnel Count] = len(df) 80   #c = df.pop(Tunnel Count) 81   #df.insert(df.shape[1], c.name, c)

試したこと

1回目のAPI結果一覧と、2回目の結果をカウントした結果を一覧化しようと試みた
指摘によろ「print(df.columns)」を確認indexの項目がないことが原因

   df = df[["system-ip", "host-name", "device-model"]]
df[Tunnel Count] = len(df)
c = df.pop(Tunnel Count)
df.insert(df.shape[1], c.name, c)

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

can110

2022/12/23 01:18

元となるdfはどのような形で、結果としてどういったdf(CSV)にしたいのかが理解できませんので 具体的なデータ例を示すと回答得られやすくなるかと思います。 (リストとカウントを一覧化とは?)
melian

2022/12/23 02:26

> "errorMessage" : "/None of [Index(["system-ip", "host-name", "device-model"], dtype = object`)] are in the [columns]/"" このエラーメッセージから判ることは df に "system-ip", "host-name", "device-model" という名前のカラムがない、ということなので、直前で print(df.columns) としてカラムの内容を確認してみるとよいかと思います。
msy47

2022/12/23 03:00

can100さん ご指摘ありがとうございます。現在のdfと、想定するdfについて追記いたしました。 melianさん ご助言ありがとうございます。確認したところ、指摘のとおり、カラムが存在しませんでした。
guest

回答1

0

ベストアンサー

提示されている元dfの形を完全に把握できているか自信がありませんが、おおむね以下のような流れでできると思います。
提示コードでのループの中の変数名dfは元のdfと区別がつかなくなるのでdf_lenとしています。

Python

1import pandas as pd 2from io import StringIO 3 4# テストデータ 5s = """deviceId system-ip bfdSessionsUP bfdSessions 610.0.0.1 10.1.0.1 7.0 7 710.0.0.2 10.2.0.2 8.0 8""" 8df = pd.read_csv(StringIO(s), sep='\s+') 9print(df) 10# deviceId system-ip bfdSessionsUP bfdSessions 11#0 10.0.0.1 10.1.0.1 7.0 7 12#1 10.0.0.2 10.2.0.2 8.0 8 13 14lens = [] # 行数を貯めておくため 15for data in df.itertuples(): 16 deviceid = data[1] 17 # 略 18 #df_len = pd.json_normalize(json_data["data"] 19 # とりあえずテストとしてIP末尾を行数とするダミーのdfを利用 20 df_len = pd.DataFrame([[0] for _ in range(int(deviceid[-1]))]) 21 len_df = len(df_len) 22 lens.append(len_df) 23 24df['TunnnelCount'] = lens 25print(df) 26# deviceId system-ip bfdSessionsUP bfdSessions TunnnelCount 27#0 10.0.0.1 10.1.0.1 7.0 7 1 28#1 10.0.0.2 10.2.0.2 8.0 8 2

投稿2022/12/23 04:37

can110

総合スコア38341

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

msy47

2022/12/23 06:19

can110さん レスポンス早い、丁寧な回答ありがとうございます! こちらで動作を確認できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問