“ValueError: cannot set a frame with no defined columns” 在追加两个数据框时出现。

huangapple go评论219阅读模式
英文:

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_dfparse_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()

huangapple
  • 本文由 发表于 2023年5月26日 14:11:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76338060.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定