chr*_*725 5 python json python-2.7 pandas
我是Python的初学者。我想做的是通过Pandas加载外汇历史价格数据的json文件,并对数据进行统计。我已经遍历了有关Pandas和解析json文件的许多主题。我想将具有额外值和嵌套列表的json文件传递给pandas数据框。我在这里遇到了问题。
我有一个json文件'EUR_JPY_H8.json'
首先,我导入所需的库,
import pandas as pd
import json
from pandas.io.json import json_normalize
Run Code Online (Sandbox Code Playgroud)
然后加载json文件,
with open('EUR_JPY_H8.json') as data_file:
data = json.load(data_file)
Run Code Online (Sandbox Code Playgroud)
我在下面有一个列表:
[{u'complete': True,
u'mid': {u'c': u'119.743',
u'h': u'119.891',
u'l': u'119.249',
u'o': u'119.341'},
u'time': u'1488319200.000000000',
u'volume': 14651},
{u'complete': True,
u'mid': {u'c': u'119.893',
u'h': u'119.954',
u'l': u'119.552',
u'o': u'119.738'},
u'time': u'1488348000.000000000',
u'volume': 10738},
{u'complete': True,
u'mid': {u'c': u'119.946',
u'h': u'120.221',
u'l': u'119.840',
u'o': u'119.888'},
u'time': u'1488376800.000000000',
u'volume': 10041}]
Run Code Online (Sandbox Code Playgroud)
然后我将列表传递给json_normalize。尝试获取嵌套在“ mid”下方的列表中的价格
result = json_normalize(data,'time',['time','volume','complete',['mid','h'],['mid','l'],['mid','c'],['mid','o']])
Run Code Online (Sandbox Code Playgroud)
但是我得到了这样的结果, json_normalize输出
“时间”数据逐行细分为每个整数。我已经检查了相关文件。我必须将字符串或列表对象传递给json_normalize的第二个参数。如何在不传递时间戳的情况下传递时间戳。
我的预期输出是:
column =
index | time | volumn | completed | mid.h | mid.l | mid.c | mid.o
Run Code Online (Sandbox Code Playgroud)
您可以通过data而无需任何其他参数。
df = pd.io.json.json_normalize(data)
df
complete mid.c mid.h mid.l mid.o time volume
0 True 119.743 119.891 119.249 119.341 1488319200.000000000 14651
1 True 119.893 119.954 119.552 119.738 1488348000.000000000 10738
2 True 119.946 120.221 119.840 119.888 1488376800.000000000 10041
Run Code Online (Sandbox Code Playgroud)
如果要更改列顺序,请使用df.reindex:
df = df.reindex(columns=['time', 'volume', 'complete', 'mid.h', 'mid.l', 'mid.c', 'mid.o'])
df
time volume complete mid.h mid.l mid.c mid.o
0 1488319200.000000000 14651 True 119.891 119.249 119.743 119.341
1 1488348000.000000000 10738 True 119.954 119.552 119.893 119.738
2 1488376800.000000000 10041 True 120.221 119.840 119.946 119.888
Run Code Online (Sandbox Code Playgroud)
OP 中的数据(最好使用 json 字符串反序列化后json.load())是一个嵌套字典列表,这是一种理想的数据结构,因为pd.json_normalize()它转换字典列表并将每个字典展平为单行。因此列表的长度决定了行数,字典中键值对的总数决定了列数。
但是,如果某个键下的值是一个列表,则情况不再如此,因为这些列表中的项目可能需要位于各自单独的行中。例如,如果my_data.json文件如下:
# my_data.json
[
{'price': {'mid': ['119.743', '119.891', '119.341'], 'time': '123'}},
{'price': {'mid': ['119.893', '119.954', '119.552'], 'time': '456'}},
{'price': {'mid': ['119.946', '120.221', '119.840'], 'time': '789'}}
]
Run Code Online (Sandbox Code Playgroud)
然后您需要将列表中的每个值作为其自己的行。在这种情况下,您可以将这些列表的路径作为record_path=参数传递。此外,您可以使每个记录都有其随附的元数据,您也可以将其路径作为meta=参数传递。
# deserialize json into a python data structure
import json
with open('my_data.json', 'r') as f:
data = json.load(f)
# normalize the python data structure
df = pd.json_normalize(data, record_path=['price', 'mid'], meta=[['price', 'time']], record_prefix='mid.')
Run Code Online (Sandbox Code Playgroud)
最终,pd.json_normalize()无法处理比这种结构更复杂的东西。例如,如果另一个元数据嵌套在另一个字典中,则它无法将另一个元数据添加到上面的示例中。根据数据,您很可能需要一个递归函数来解析它(仅供参考,pd.json_normalize()也是一个递归函数,但它适用于一般情况,不适用于许多特定对象)。
很多时候,您需要结合使用explode()等pd.DataFrame(col.tolist())来完全解析数据。
Pandas 也有一个便利的功能pd.read_json(),但它的局限性更大,pd.json_normalize()因为它只能正确解析一个嵌套级别的 json 数组。但与此不同的是pd.json_normalize(),它在底层反序列化 json 字符串,因此您可以直接将 json 文件的路径传递给它(不需要json.load())。换句话说,以下两个产生相同的输出:
df1 = pd.read_json("my_data.json")
df2 = pd.json_normalize(data, max_level=0) # here, `data` is deserialized `my_data.json`
df1.equals(df2) # True
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16406 次 |
| 最近记录: |