用正确的 Dtype 将带有无意义键的 json 读入 pandas data.frame
Posted
技术标签:
【中文标题】用正确的 Dtype 将带有无意义键的 json 读入 pandas data.frame【英文标题】:Read json with meaningless keys into pandas data.frame with correct Dtype 【发布时间】:2022-01-13 17:34:34 【问题描述】:在一个项目中,我收到需要读入 pandas data.frame 的 json。
格式如下所示(列和行更多):
"a;b;c;d":
"1":"100;14/09/2020;0.5;XK3",
"2":"NA;17/09/2020;0.95;NA",
"3":"102;NA;NA;KZ2"
我可以拆分字符串,但我的类型不是我想要的。有没有自动转换u
中的列的方法?
from io import StringIO
import pandas as pd
TESTDATA = StringIO("""
"a;b;c;d":
"1":"100;14/09/2020;0.5;XK3",
"2":"NA;17/09/2020;0.95;NA",
"3":"102;NA;NA;KZ2"
""")
df = pd.read_json(TESTDATA)
df.head(10)
vnames = df.columns[0].split(';')
u = (df[df.columns[0]].str.split(';', expand=True)
.set_axis(vnames, axis=1, inplace=False)).convert_dtypes()
print(u.head(10))
print(u.info())
我希望 Dtype 为 int64, datetime64, float64, str
。
【问题讨论】:
你的真实数据有相同的形式吗?一个单键的字典? @Corralien,是的,我的真实数据具有相同的形式。文件中有多个文件,文件中的列也比较多,但总体上是一样的。 你的 json 有什么“不正确”的地方? @balmy,json格式有效,但键值对无意义。这是一个以可怕的方式嵌入到 json 中的表格。 所以它是“正确的”JSON,但不是你想要的。请编辑您的问题标题以更正此问题。 【参考方案1】:您可以执行以下操作:
from io import StringIO
import pandas as pd
import numpy as np
TESTDATA = StringIO("""
"a;b;c;d":
"1":"100;14/09/2020;0.5;XK3",
"2":"NA;17/09/2020;0.95;NA",
"3":"102;NA;NA;KZ2"
""")
df = pd.read_json(TESTDATA)
df.head(10)
vnames = df.columns[0].split(';')
u = (df[df.columns[0]].str.split(';', expand=True)
.set_axis(vnames, axis=1, inplace=False))
u = u.apply(lambda x: x.str.strip()).replace('NA', np.nan)
u = u.to_json()
u = pd.read_json(u).convert_dtypes()
print(u.head(10))
print(u.info())
【讨论】:
它将日期保留为字符串,但它或多或少是我想要的。因此,如果我在接下来的几天内没有得到可以满足日期要求的答案,我会接受这个答案,因为它是一项重大改进。【参考方案2】:在创建 DataFrame 之前尝试显式类型转换字符串值,如下例所示:
import json
import pandas as pd
s_src = ''' "a;b;c;d":
"1":"100;14/09/2020;0.5;XK3",
"2":"NA;17/09/2020;0.95;NA",
"3":"102;NA;NA;KZ2"'''
s = json.loads(s_src)
# per-column type conversion
typeconv = [int, pd.to_datetime, float, str]
for k1, subd in s.items():
cols = k1.split(';')
rows = []
for k, v in subd.items():
row = v.split(';')
conv_row =[]
for cvt, r in zip(typeconv, row):
# screen for missing values
if r == 'NA':
conv_row.append(None)
else:
# apply the conversion function for this column
conv_row.append(cvt(r))
rows.append(conv_row)
df = pd.DataFrame(rows, columns=cols)
【讨论】:
我的目标是避免手动类型转换(硬编码)值。否则,我可以使用类似numericCols = ["c"] \\ u[numericCols] = u[numericCols].apply(pd.to_numeric,errors='coerce')
以上是关于用正确的 Dtype 将带有无意义键的 json 读入 pandas data.frame的主要内容,如果未能解决你的问题,请参考以下文章