У меня есть следующий сценарий очистки, мне нужно получить элементы внутри цикла foor "items2". Сценарий печатает все элементы, но позже dataframe возвращает «имя» и «tPlan» как NaN. Есть идеи, почему?
import requests
import json
import csv
import sys
from bs4 import BeautifulSoup
base_url = "xxxx"
username = "xxxx"
password = "xxxx"
toget = data
allowed_results = 50
max_results = "maxResults = " + str(allowed_results)
tc = "/testcycles?"
result_count = -1
start_index = 0
df = pd.DataFrame(
columns=['id', 'name', 'gId', 'dKey', 'tPlan'])
for eachId in toget['TPlan_ID']:
while result_count != 0:
start_at = "startAt = " + str(start_index)
url = url = f'{base_url}{eachId}{tc}&{start_at}&{max_results}'
response = requests.get(url, auth=(username, password))
json_response = json.loads(response.text)
print(json_response)
page_info = json_response["meta"]["pageInfo"]
start_index = page_info["startIndex"] + allowed_results
result_count = page_info["resultCount"]
items2 = json_response["data"]
print(items2)
for item in items2:
print (item["id"])
print (item["fields"]["name"])
print (item["fields"]["gId"])
print (item["fields"]["dKey"])
print (item["fields"]["tPlan"])
temporary_df = pd.DataFrame([item], columns=['id', 'name', 'gId', 'dKey', 'tPlan'])
df = df.append(temporary_df, ignore_index=True)
Используйте это для цикла.
for item in items2:
df = df.append({'id': item['id'], **item['fields']}, ignore_index=True)
Я делаю предположение, что items2
будет выглядеть примерно так.
items2 = [
{ 'id': 0, 'fields': {'name': 'prop1', 'gId': 100, 'dKey': 'key1', 'tPlan': 'plan1'}},
{ 'id': 1, 'fields': {'name': 'prop2', 'gId': 200, 'dKey': 'key2', 'tPlan': 'plan2'}},
{ 'id': 2, 'fields': {'name': 'prop3', 'gId': 300, 'dKey': 'key3', 'tPlan': 'plan3'}},
]
Вы не можете создать свой предполагаемый фрейм данных, так как структура item
такая.
{'id': 2, 'fields': {'name': 'prop3', 'gId': 300, 'dKey': 'key3', 'tPlan': 'plan3'}}
что приводит к заполнению temporary_df
NaN.
id name gId dKey tPlan fields
0 0 NaN NaN NaN NaN key1
1 0 NaN NaN NaN NaN 100
2 0 NaN NaN NaN NaN prop1
3 0 NaN NaN NaN NaN plan1
4 1 NaN NaN NaN NaN key2
5 1 NaN NaN NaN NaN 200
6 1 NaN NaN NaN NaN prop2
7 1 NaN NaN NaN NaN plan2
8 2 NaN NaN NaN NaN key3
9 2 NaN NaN NaN NaN 300
10 2 NaN NaN NaN NaN prop3
11 2 NaN NaN NaN NaN plan3
То, что вам нужно передать в качестве аргумента pd.DataFrame, представляет собой структуру dict, например
{'id': 2, 'name': 'prop3', 'gId': 300, 'dKey': 'key3', 'tPlan': 'plan3'}
Обратите внимание на отсутствующий fields
dict здесь, все пары ключ-значение из fields
добавляются в item
. Использование этого измененного словаря приведет к temporary_df
лайку
id name gId dKey tPlan
0 0 prop1 100 key1 plan1
1 1 prop2 200 key2 plan2
2 2 prop3 300 key3 plan3
Чтобы внести это изменение в структуру элемента, вы должны сделать это
new_item = {'id': item['id']}
for key, value in item['fields'].items():
new_item[key] = value
Но вы можете написать это кратко, используя оператор распаковки**
new_item = {'id': item['id'], **item['fields']}
Теперь мы можем использовать pass new_item
в качестве аргумента для pd.DataFrame
.
temp_df = pd.DataFrame({ 'id': item['id'], **item['fields']}, index=(i,)) # i here is the row index of the DataFrame
После внесения этих изменений ваш цикл for должен выглядеть примерно так:
for i, item in enumerate(items2):
new_item = {'id': item['id'], **item['fields']}
temp_df = pd.DataFrame(new_item, index=(i,))
df = df.append(temp_df, ignore_index=True)
Мы можем сделать это немного более кратким, напрямую передав new_item
в pd.DataFrame.append
Таким образом, в конце концов, этот код должен работать.
for item in items2:
new_item = {'id': item['id'], **item['fields']}
df = df.append(new_item, ignore_index=True)
Не могли бы вы добавить значение
items2
в свой вопрос. Не весь список, а только несколько пунктов будет достаточно.