【问题标题】:Pandas DataFrame created for each row为每一行创建的 Pandas DataFrame
【发布时间】:2018-11-28 05:06:12
【问题描述】:

我正在尝试将 JSON 格式的数据从 API 传递到 Pandas DataFrame。我无法让 pandas.read_json 处理 API 数据,所以我确信这不是最好的解决方案,但我目前有 for loop 通过 JSON 运行以提取我想要的值。

这是我所拥有的:

import json
import urllib.request
import pandas as pd

r = urllib.request.urlopen("https://graph.facebook.com/v3.1/{page-id}/insights?access_token={access-token}&pretty=0&metric=page_impressions%2cpage_engaged_users%2cpage_fans%2cpage_video_views%2cpage_posts_impressions").read()

output = json.loads(r)

for item in output['data']:
    name = item['name']
    period = item['period']
    value = item['values'][0]['value']

    df = [{'Name': name, 'Period': period, 'Value': value}]

    df = pd.DataFrame(df)

    print(df)

这里是来自 API 的 JSON 的摘录:

    {
  "data": [
    {
      "name": "page_video_views",
      "period": "day",
      "values": [
        {
          "value": 634,
          "end_time": "2018-11-23T08:00:00+0000"
        },
        {
          "value": 465,
          "end_time": "2018-11-24T08:00:00+0000"
        }
      ],
      "title": "Daily Total Video Views",
      "description": "Daily: Total number of times videos have been viewed for more than 3 seconds. (Total Count)",
      "id": "{page-id}/insights/page_video_views/day"
    },

我现在面临的问题是因为 For 循环(我相信),每一行数据都被插入到自己的 DataFrame 中,如下所示:

               Name Period  Value
0  page_video_views    day    465
               Name Period  Value
0  page_video_views   week   3257
               Name   Period  Value
0  page_video_views  days_28   9987
               Name Period  Value
0  page_impressions    day   1402

我怎样才能像这样轻松地将它们全部传递到同一个 DataFrame 中?

               Name Period  Value
0  page_video_views    day    465
1  page_video_views   week   3257
2  page_video_views  days_28   9987
3  page_impressions    day   1402

再次,我知道这很可能不是最佳解决方案,因此非常欢迎任何有关如何改进任何方面的建议。

【问题讨论】:

  • 你能显示预期的输出吗?
  • 刚刚编辑了预期的输出

标签: python python-3.x pandas dataframe


【解决方案1】:

您可以创建字典列表并传递给DataFrame 构造函数:

L = []
for item in output['data']:
    name = item['name']
    period = item['period']
    value = item['values'][0]['value']

    L.append({'Name': name, 'Period': period, 'Value': value})

df = pd.DataFrame(L)

或使用list comprehension:

L = [({'Name': item['name'], 'Period': item['period'], 'Value': item['values'][0]['value']}) 
       for item in output['data']]

df = pd.DataFrame(L)
print (df)
               Name Period  Value
0  page_video_views    day    634

测试样本:

output = {
  "data": [
    {
      "name": "page_video_views",
      "period": "day",
      "values": [
        {
          "value": 634,
          "end_time": "2018-11-23T08:00:00+0000"
        },
        {
          "value": 465,
          "end_time": "2018-11-24T08:00:00+0000"
        }
      ],
      "title": "Daily Total Video Views",
      "description": "Daily: Total number of times videos have been viewed for more than 3 seconds. (Total Count)",
      "id": "{page-id}/insights/page_video_views/day"
    }]}

【讨论】:

  • 列表理解正是我需要的!像魅力一样工作。
【解决方案2】:

json加载到dataframe后尝试转换字典like:

output = json.loads(r)
df = pd.DataFrame.from_dict(output , orient='index')
df.reset_index(level=0, inplace=True)

【讨论】:

  • df = pd.DataFrame.from_dict(output , orient='index') 上抛出错误“预期列表,得到字典”
  • 如果我可以让它工作并避免 For 循环,我会很高兴,但出于某种原因,来自 Graph API 的 JSON 似乎并不能很好地发挥作用
【解决方案3】:

如果您从 url 获取数据。我会建议这种方法并仅传递存储在属性下的数据

import request
data=request.get("url here").json('Period')

Period 现在是字典,您现在可以调用 pd.DataFrame.from_dict(data) 来解析数据

df = pd.DataFrame.from_dict(Period)

【讨论】:

    猜你喜欢
    • 2021-06-20
    • 1970-01-01
    • 2019-07-08
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多