英文:
While appending 2 dataframes getting "ValueError: cannot set a frame with no defined columns"
问题
数据帧1位于一个函数内,数据帧2位于主函数中,当我运行主函数时,它从JSON中附加值并存储在result_df
中,出现ValueError: cannot set a frame with no defined columns
错误。
为什么我要在主函数中创建数据帧2?
我在其他函数中使用数据帧2(total_device_df)将其转换为CSV。
可重现的代码:
import pandas as pd
import os
import json
class KatsRequest:
currDir = os.getcwd()
def parse_json_response():
filename = "my_json_file.json"
device_name = ["Trona", "Sheldon"]
"创建数据帧以存储结果"
column_names = ["DEVICE", "STATUS", "LAST UPDATED"]
result_df = pd.DataFrame(columns=column_names)
my_json_file = currDir + '/' + filename
for i in range(len(device_name)):
my_device_name = device_name[i]
with open(my_json_file) as f:
data = json.load(f)
for devices in data:
device_types = devices['device_types']
if my_device_name in device_types['name']:
if device_types['name'] == my_device_name:
device = devices['device_types']['name']
last_updated = devices['devices']['last_status_update']
device_status = devices['devices']['status']
result_df.loc[len(result_df)] = {'DEVICE': device, 'STATUS': device_status, 'LAST UPDATED': last_updated}
return result_df
def main():
total_device_df = pd.DataFrame()
total_device_df.loc[len(total_device_df)] = KatsRequest().parse_json_response()
if __name__ == '__main__':
main()
这是我的JSON文件内容:(保存在当前路径中,命名为"my_json_file.json")
[{"devices": {"id": 34815, "last_status_update": "2023-05-25 07:56:49", "status": "idle" }, "device_types": {"name": "Trona"}}, {"devices": {"id": 34815, "last_status_update": "2023-05-25 07:56:49", "status": "idle" }, "device_types": {"name": "Sheldon"}}]
输出:
ValueError: cannot set a frame with no defined columns
这里缺少/错误了什么?
英文:
Dataframe 1 is inside a function and Dataframe 2 is in main function when I run main function, it appends the values from a JSON and stores in result_df
and getting ValueError: cannot set a frame with no defined columns
error
Why I am creating Dataframe2 in main function?
I am using Dataframe2 (total_device_df) in other functions to convert to csv.
Reproducible code:
import pandas as pd
import os
import json
class KatsRequest:
currDir = os.getcwd()
def parse_json_response():
filename = "my_json_file.json"
device_name = ["Trona", "Sheldon"]
"creating dataframe to store result"
column_names = ["DEVICE", "STATUS", "LAST UPDATED"]
result_df = pd.DataFrame(columns=column_names)
my_json_file = currDir + '/' + filename
for i in range(len(device_name)):
my_device_name = device_name[i]
with open(my_json_file) as f:
data = json.load(f)
for devices in data:
device_types = devices['device_types']
if my_device_name in device_types['name']:
if device_types['name'] == my_device_name:
device = devices['device_types']['name']
last_updated = devices['devices']['last_status_update']
device_status = devices['devices']['status']
result_df.loc[len(result_df)] = {'DEVICE': device, 'STATUS': device_status, 'LAST UPDATED': last_updated}
return result_df
def main()
total_device_df = pd.DataFrame()
total_device_df.loc[len(total_device_df)] = KatsRequest().parse_json_response(filename, device_names)
if __name__ == '__main__':
main()
Here is my JSON file contents: (save in your current path named as "my_json_file.json")
[{"devices": {"id": 34815, "last_status_update": "2023-05-25 07:56:49", "status": "idle" }, "device_types": {"name": "Trona"}}, {"devices": {"id": 34815, "last_status_update": "2023-05-25 07:56:49", "status": "idle" }, "device_types": {"name": "Sheldon"}}]
Output:
ValueError: cannot set a frame with no defined columns
What is missing/wrong here?
答案1
得分: 1
(你的示例无法重现)
如果你想要合并 total_device_df
和 parse_json_response
返回的数据框,你需要使用 pd.concat
。
def main():
total_device_df = pd.DataFrame()
total_device_df = pd.concat([total_device_df, KatsRequest().parse_json_response(filename, device_names)])
或者简化为:
def main():
total_device_df = KatsRequest().parse_json_response(filename, device_names)
完整示例:
import os
import json
import pandas as pd
currDir = os.getcwd()
filename = 'my_json_file.json'
device_names = ['Trona', 'Sheldon']
class KatsRequest:
def parse_json_response(self, filename, device_name):
# 创建用于存储结果的数据框
column_names = ["DEVICE", "STATUS", "LAST UPDATED"]
result_df = pd.DataFrame(columns=column_names)
my_json_file = currDir + '/' + filename
for i in range(len(device_name)):
my_device_name = device_name[i]
with open(my_json_file) as f:
data = json.load(f)
for devices in data:
device_types = devices['device_types']
if my_device_name in device_types['name']:
if device_types['name'] == my_device_name:
device = devices['device_types']['name']
last_updated = devices['devices']['last_status_update']
device_status = devices['devices']['status']
result_df.loc[len(result_df)] = {'DEVICE': device, 'STATUS': device_status, 'LAST UPDATED': last_updated}
return result_df
def main():
total_device_df = pd.DataFrame()
total_device_df = pd.concat([total_device_df, KatsRequest().parse_json_response(filename, device_names)])
print(total_device_df)
if __name__ == '__main__':
main()
输出:
>>> total_device_df
DEVICE STATUS LAST UPDATED
0 Trona idle 2023-05-25 07:56:49
1 Sheldon idle 2023-05-25 07:56:49
更新:
一种简便的方法是使用 pd.json_normalize
:
with open('my_json_file.json') as jp:
data = json.load(jp)
total_device_df = (pd.json_normalize(data).loc[lambda x: x['device_types.name'].isin(device_names)]
.rename(columns=lambda x: x.split('.', maxsplit=1)[-1].upper()))
输出:
>>> total_device_df
ID LAST_STATUS_UPDATE STATUS NAME
0 34815 2023-05-25 07:56:49 idle Trona
1 34815 2023-05-25 07:56:49 idle Sheldon
如何在完整示例代码中使用 pd.json_normalize
方法?
import os
import json
import pandas as pd
currDir = os.getcwd()
filename = 'my_json_file.json'
device_names = ['Trona', 'Sheldon']
class KatsRequest:
def parse_json_response(self, filename, device_name):
# 创建用于存储结果的数据框
dmap = {
'device_types.name': 'DEVICE',
'devices.status': 'STATUS',
'devices.last_status_update': 'LAST STATUS'
}
my_json_file = currDir + '/' + filename
with open(my_json_file) as f:
data = json.load(f)
results_df = (pd.json_normalize(data)[dmap.keys()].rename(columns=dmap)
.loc[lambda x: x['DEVICE'].isin(device_names)])
return results_df
def main():
total_device_df = pd.DataFrame()
total_device_df = pd.concat([total_device_df, KatsRequest().parse_json_response(filename, device_names)])
print(total_device_df)
if __name__ == '__main__':
main()
希望这些翻译对你有帮助。
英文:
(Your example is not reproducible)
You have to use pd.concat
if you want to use merge total_device_df
and the dataframe returned by parse_json_response
.
def main():
total_device_df = pd.DataFrame()
total_device_df = pd.concat([total_device_df, KatsRequest().parse_json_response(filename, device_names)])
Or simply:
def main():
total_device_df = pd.DataFrame()
total_device_df = KatsRequest().parse_json_response(filename, device_names)
Full example:
import os
import json
import pandas as pd
currDir = os.getcwd()
filename = 'my_json_file.json'
device_names = ['Trona', 'Sheldon']
class KatsRequest:
def parse_json_response(self, filename, device_name):
# creating dataframe to store result
column_names = ["DEVICE", "STATUS", "LAST UPDATED"]
result_df = pd.DataFrame(columns=column_names)
my_json_file = currDir + '/' + filename
for i in range(len(device_name)):
my_device_name = device_name[i]
with open(my_json_file) as f:
data = json.load(f)
for devices in data:
device_types = devices['device_types']
if my_device_name in device_types['name']:
if device_types['name'] == my_device_name:
device = devices['device_types']['name']
last_updated = devices['devices']['last_status_update']
device_status = devices['devices']['status']
result_df.loc[len(result_df)] = {'DEVICE': device, 'STATUS': device_status, 'LAST UPDATED': last_updated}
return result_df
def main():
total_device_df = pd.DataFrame()
total_device_df = pd.concat([total_device_df, KatsRequest().parse_json_response(filename, device_names)])
print(total_device_df)
if __name__ == '__main__':
main()
Output:
>>> total_device_df
DEVICE STATUS LAST UPDATED
0 Trona idle 2023-05-25 07:56:49
1 Sheldon idle 2023-05-25 07:56:49
Update:
A painless way is to use pd.json_normalize
:
with open('my_json_file.json') as jp:
data = json.load(jp)
total_device_df = (pd.json_normalize(data).loc[lambda x: x['device_types.name'].isin(device_names)]
.rename(columns=lambda x: x.split('.', maxsplit=1)[-1].upper()))
Output:
>>> total_device_df
ID LAST_STATUS_UPDATE STATUS NAME
0 34815 2023-05-25 07:56:49 idle Trona
1 34815 2023-05-25 07:56:49 idle Sheldon
> How to use pd.json_normalize method in full example code?
import os
import json
import pandas as pd
currDir = os.getcwd()
filename = 'my_json_file.json'
device_names = ['Trona', 'Sheldon']
class KatsRequest:
def parse_json_response(self, filename, device_name):
# creating dataframe to store result
dmap = {
'device_types.name': 'DEVICE',
'devices.status': 'STATUS',
'devices.last_status_update': 'LAST STATUS'
}
my_json_file = currDir + '/' + filename
with open(my_json_file) as f:
data = json.load(f)
results_df = (pd.json_normalize(data)[dmap.keys()].rename(columns=dmap)
.loc[lambda x: x['DEVICE'].isin(device_names)])
return results_df
def main():
total_device_df = pd.DataFrame()
total_device_df = pd.concat([total_device_df, KatsRequest().parse_json_response(filename, device_names)])
print(total_device_df)
if __name__ == '__main__':
main()
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论