【问题标题】:Python JSON to CSV conversionPython JSON 到 CSV 转换
【发布时间】:2020-12-26 16:42:21
【问题描述】:

我正在研究一个示例,但遇到了一些问题。我是python的初学者,并尝试提高自己。我正在尝试使用 openweather api 并从中获取一些数据,然后将这些数据写入 csv 文件。我的代码的目的是输入一个包含城市名称的 txt 文件,我想获取城市名称、国家代码、纬度、温度、风速、风向。然后将它们写入 csv 文件。我可以输入 txt 文件或通过命令行输入获取数据,但不能两者兼得。而且我想将数据写入 csv 文件。请你帮助我好吗?我可以将其写入控制台,但我需要将它们写入 csv 文件。但是,我无法将我的 json 对象转换为 csv

我的输入.txt

Los Angeles
San Francisco
...

我的代码:

import requests
from pprint import pprint
import csv
import pandas as pd

file = input("Input the filepath: ")

with open(file) as f:
    for line in f:
        line = line.strip()

        API_key = "MYAPIKEY"
        base_url = "http://api.openweathermap.org/data/2.5/weather?"
        headers = {'content-type': 'application/json'}

        city_name = line
       
        Final_url = base_url + "appid=" + API_key + "&q=" + city_name

        weather_data = requests.get(Final_url).json()

        print("\nCurrent Weather" + city_name + ":\n")
        weather_data = requests.get(Final_url, headers=headers)

        f = open('weather_data_file.csv', "w")
        f.write(weather_data.text)
        f.close()
        print(f)

编辑后的问题:

CSV 文件只包含最后一个城市数据,数据不在 如果我用 excel 打开,格式正确

它输出的数据:

{"coord":{"lon":-122.42,"lat":37.77},"weather":[{"id":802,"main":"Clouds","description":"scattered clouds","icon":"03d"}],"base":"stations","main":{"temp":284.74,"feels_like":280.59,"temp_min":283.15,"temp_max":286.48,"pressure":1024,"humidity":76},"visibility":10000,"wind":{"speed":5.1,"deg":260},"clouds":{"all":40},"dt":1609003065,"sys":{"type":1,"id":5817,"country":"US","sunrise":1608996226,"sunset":1609030632},"timezone":-28800,"id":5391959,"name":"San Francisco","cod":200}

【问题讨论】:

  • 在询问有关 Pandas 的问题时,请始终包含 pandas 标签,如 python 标签 wiki 中所述。
  • 你能发布weather_data,假设它不是太大吗? (然后只是一个示例)?
  • 已编辑问题,请您再看一遍@tdelaney
  • JSON 是表示数据的序列化字符串。您的 weather_data 不是 JSON - 它是从 JSON 创建的 python 对象的集合。 pd.from_json 旨在反序列化 JSON 并从中拉出一个表(如果 JSON 看起来不像 pandas 的表,它会失败)。您可能能够创建像 df = pd.DataFrame(weather_data) 这样的数据框 - 假设 weather_data 是一个包含列表的字典。我们需要看数据才能知道。
  • 现在你得到weather_data 两次——用第二个响应对象覆盖第一个json。您的原始代码正在执行pprint(weather_data) - 这是好东西。

标签: python pandas api csv


【解决方案1】:

要将您的 JSON 文件写入 CSV 文件:

import pandas as pd

if __name__ == "__main__":
    df = pd.read_json (r'ajsonfile.json')
    df.to_csv (r'filename.csv', index = None)

从 API 写入 JSON 数据:

# Get JSON Data
weather_data = requests.get(yourURL, headers=yourHeaders)

# Write to .CSV
f = open('weather_data_file.csv', "w")
f.write(weather_data.text)
f.close()

【讨论】:

  • 我试过你的代码,但没有用。我的 json 文件名是 weather_data,我在你的代码中看不到这个变量
  • 我刚刚写了一个示例,让您了解如何从 JSON 文件解析为 CSV 文件。您可以根据需要管理/命名文件:)
  • 我是这样写的,但是有很多错误; df = pd.read_json(weather_data) df.to_csv (r'test.csv', index = None)
  • 注意,weather_data 应该是一个 json 文件名。如果像你一样,请告诉我那个错误
  • @daprogramma,“大量错误”不是很有帮助。 具体错误更好。如果更容易格式化,请随时编辑您的问题。请阅读How to Ask
【解决方案2】:

JavaScript Object Notation (JSON) 是数据的序列化表示。 pandas.read_json 尝试解码 JSON 并从中构建数据帧。在您使用requests 读取数据并使用.json() 调用将其反序列化为python 之后,它不再是JSON,pandas.read_json 将不起作用。

有时您可以直接从 python 对象构建数据框,但在这种情况下,您还有一个额外的问题。您一次只要求一行数据(一个城市),其信息嵌套在多个字典中。您可以使用 python 将接收到的城市数据扁平化为您想要的数据子集。而且由于您只是逐行工作,因此请使用csv 模块随时编写行。

解决办法是

import requests
from pprint import pprint
import csv

openweathermap_city_csv_header = ["City Name", "Country Code", "Lat", "Long", "Temperature",
    "Wind Speed", "Wind Direction"]

def openweathermap_city_flatten_record(record):
    coord = record["coord"]
    wind = record["wind"]
    return { "City Name":record["name"], 
        "Country Code":record["Code"],
        "Lat":coord["lat"],
        "Long":coord["lon"],
        "Temperature":record["main"]["temp"],
        "Wind Speed":wind["speed"],
        "Wind Direction":wind["deg"] }
    
file = input("Input the filepath: ")

with open(file) as cities, open('weather_data_file.csv', "w") as outfile:
    writer = csv.DictWriter(outfile, openweathermap_city_csv_header)
    for line in f:
        line = line.strip()
        API_key = "MYAPIKEY"
        base_url = "http://api.openweathermap.org/data/2.5/weather?"
        headers = {'content-type': 'application/json'}
        city_name = line
        Final_url = base_url + "appid=" + API_key + "&q=" + city_name
        weather_data = requests.get(Final_url, headers=headers).json()
        print("\nCurrent Weather" + city_name + ":\n")
        writer.writerow(openweathermap_city_flatten_record(weather_data))

【讨论】:

  • 您好,非常感谢您的回答,我明白了,但有一个错误,请您看看; writer = csv.DictWriter(openweathermap_city_csv_header) TypeError: __init__() 缺少 1 个必需的位置参数:'fieldnames'
  • 我错过了文件对象。
  • 非常感谢,这对我帮助很大,也学到了这个主题:)
猜你喜欢
  • 2021-08-21
  • 1970-01-01
  • 2013-07-05
  • 2023-03-19
  • 2015-08-07
  • 1970-01-01
  • 2018-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多