如何在 Pandas DataFrame 中对每一行应用 json.loads?

7

我有一个包含metadata列的pandas数据框。该列包含嵌套字典。我想要在每一行中消除值周围的单引号。json.loads(data)对于我传递的单个值有效。

以下是示例:

data = '{"dek": "<p>Don\'t forget to buy a card</p>", "links": {"edit": {"dev": "...}}}'
data_json = json.loads(data)
data

输出结果: {"dek": "<p>别忘了买一张卡片</p>", "links": {"edit": {"dev": "...}}}

然而,当我尝试将其应用于metadata列中的每一行时,它会出现错误。以下是代码:

for index, row in sample_df.iterrows():
    sample_df['metadata'] = json.loads(sample_df["metadata"])

类型错误:JSON对象必须是str、bytes或bytearray类型,而不是Series类型

数据集示例:

id    metadata                                         title 
123  {"dek": "<p>Student loan debt is crippling a g... channel
124  {"dek": "<p>Student loan debt is crippling a...   fashion
3个回答

8

尝试使用这段代码:

sample_df['metadata'] = sample_df['metadata'].apply(json.loads)

Panda的apply函数,会将该函数应用于序列中的每个值。非常有用,因为您可以跳过对每行的迭代。 如果您想获取有关此函数以及可以更改的参数的更多信息,请参阅官方文档这里


2
嗯,它给了我完全相同的错误:TypeError: JSON对象必须是str、bytes或bytearray类型,而不是dict - Sonya
在 for 循环之外,正确的。我编辑了我的问题并提供了数据集的示例。metadata 列的类型是 Series。 - Sonya
我运行了以下代码:sample_df['metadata'] = sample_df['metadata'].apply(json.loads) 这一次没有出错,但是该行中单个值的输出仍然在字典周围有引号。我运行了这个命令:val = sample_df['metadata'].values[0] - Sonya
好的,我明白了。如果您查看数据框,您将看不到字典周围的引号,但是在json.loads之后存储在元数据列中的值是字符串类型;因此,如果检索单个值,则输出为字符串。如果您能更好地解释您的目标,我可以尝试更好地帮助您。 - Simone Coslovich
1
抱歉回复晚了。你可以尝试这样做:for items in df['metadata3']: for key, value in items.items(): print(key)当然要注意正确的缩进。 - Simone Coslovich
显示剩余4条评论

0

编辑:我理解错了问题。你想将字符串转换为Python字典。这里是一个完整的、可工作的示例。

from io import StringIO
import json
import pandas as pd

# Read data
s = StringIO("""id,metadata,title 
123,{"dek": "<p>Student loan</p>"},channel
124,{"dek": "<p>Student loan</p>"},fashion""")
df = pd.read_csv(s)

df.loc[:, "metadata"] = df.loc[:, "metadata"].apply(json.loads)
df.head()

# id    metadata    title
# 0 123 {'dek': '<p>Student loan</p>'}  channel
# 1 124 {'dek': '<p>Student loan</p>'}  fashion

除了@Simone Coslovich的答案,你还可以使用DataFrame.to_json


我也尝试过这个方法:sample_df['metadata'] = sample_df['metadata'].to_json 但是它给了我一个错误:TypeError: cannot concatenate object of type '<class 'numpy.ndarray'>'; only Series and DataFrame objs are valid。这很奇怪,因为这一列是Series类型的... - Sonya
运行了以下代码:df.loc[:, "metadata"] = df.loc[:, "metadata"].apply(json.loads),但是得到了相同的错误提示,即TypeError: the JSON object must be str, bytes or bytearray, not dict - Sonya
这意味着 df["metadata"] 已经是一个 dict 了... 那问题解决了吗? - jkr
用以下代码解决:sample_df["new_column"] = sample_df.metadata.apply(json.loads) - Sonya

0

这里是答案:

sample_df["new_column"] = sample_df.metadata.apply(json.loads)

输出结果为:{"dek": "<p>不要忘记买卡片</p>", "links": {"edit": {"dev": "...}}}


2
另外两个答案(https://dev59.com/vLnoa4cB1Zd3GeqPLzGM#60174691 和 https://dev59.com/vLnoa4cB1Zd3GeqPLzGM#60174642)已经展示了这一点... - jkr
@jakub 这些是针对同一个问题的答案(我自己发布的),但都没有起作用。我发布了一个特别适用于我的问题的答案。 - Sonya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接