如何从包含json数据列表的Pandas列创建列表?

oxiaedzo  于 2023-01-19  发布在  其他
关注(0)|答案(1)|浏览(159)

这是我在StackOverflow上问的第一个问题,所以请不要太严厉地把我撕成碎片。
我有一个PandasDataFrame包含一个“fieldsOfInterest”列与JSON数据,类似于此(可能不是一个准确的复制,将afk几个小时,然后更新此-希望你能隐藏在这里的问题):

In: 
df = pd.DataFrame([
        ["1", [{"code":"FOI_AGRICULTURE_FOOD|FOI_AF_FOOD_INDUSTRY"}, {"code":"FOI_AGRICULTURE_FOOD|FOI_AF_FORESTRY"}]],
        ["2", [{"code":"FOI_AGRICULTURE_FOOD|FOI_AF_SOMETHING_ELSE"}, {"code":"FOI_AGRICULTURE_FOOD|FOI_AF_FORESTRY"}]]
], columns = ["id", "fieldOfInterest"])
df
Out:
  id                                    fieldOfInterest
0  1  [{'code': 'FOI_AGRICULTURE_FOOD|FOI_AF_FOOD_IN...
1  2  [{'code': 'FOI_AGRICULTURE_FOOD|FOI_AF_SOMETHI...

我想要做的是添加一个新列,对于每个条目,该列包含旧列中相关条目中所有“code”元素的列表,因此对于上面的第一个条目

['FOI_AGRICULTURE_FOOD|FOI_AF_FOOD_INDUSTRY', 
 'FOI_AGRICULTURE_FOOD|FOI_AF_FORESTRY']

我有一个适用于单行的解决方案:

foi_normalized = pd.json_normalize(df["fieldsOfInterest"].iloc[1])
foi_codes = foi_normalized["code"]
foi_list = foi_codes.tolist()
print(foi_list)

但当我尝试用类似的方法来写整个专栏时...

def interest_reader(foi_old):
    foi_normalized = pd.json_normalize(foi_old)
    foi_codes = foi_normalized["code"]
    foi_list = foi_codes.tolist()
    return foi_list
df["fieldsOfInterest_new"] = df["fieldsOfInterest"].apply(interest_reader)

我得到了下面的错误:

File "...", line 15, in <module>
df["fieldsOfInterest_new"] =  df["fieldsOfInterest"].apply(interest_reader)
                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "...", line 4771, in apply
return SeriesApply(self, func, convert_dtype, args, kwargs).apply()
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "...", line 1105, in apply
return self.apply_standard()
       ^^^^^^^^^^^^^^^^^^^^^
File "...", line 1156, in apply_standard
mapped = lib.map_infer(
         ^^^^^^^^^^^^^^
File "pandas\_libs\lib.pyx", line 2918, in pandas._libs.lib.map_infer
File "...", line 11, in interest_reader
foi_normalized = pd.json_normalize(foi_old)
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^
File "...", line 446, in _json_normalize
raise NotImplementedError
NotImplementedError

我尝试过其他几种方法,但都不起作用。我现在想把值简单地当作字典来处理,并对每个条目循环遍历每个条目,以获得“code”键的每个值。我很高兴有任何指针,谢谢!

bweufnob

bweufnob1#

您可以首先转换每个元素使用explode将列表的(字典)添加到一个新行中。新列id将这些新行分配给原始 Dataframe 的索引(数据来源于该 Dataframe )。然后,您可以使用json_normalize从字典中提取值。最后,可以收集来自原始 Dataframe 中同一行的所有元素,并在所述列id上使用groupby构建列表。

import pandas as pd

# setup your sample data
df = pd.DataFrame([
        ["1", [{"code":"FOI_AGRICULTURE_FOOD|FOI_AF_FOOD_INDUSTRY"}, {"code":"FOI_AGRICULTURE_FOOD|FOI_AF_FORESTRY"}]],
        ["2", [{"code":"FOI_AGRICULTURE_FOOD|FOI_AF_SOMETHING_ELSE"}, {"code":"FOI_AGRICULTURE_FOOD|FOI_AF_FORESTRY"}]]
], columns = ["id", "fieldsOfInterest"])

# transform each element (the dicts) into a separate row
result = df.explode('fieldsOfInterest')

# extract the values from the dict
result['code'] = pd.json_normalize(result['fieldsOfInterest'])

# collect the element in a list
result.groupby('id')['code'].agg(list)

这导致了系列

id
1    [FOI_AGRICULTURE_FOOD|FOI_AF_FOOD_INDUSTRY, FO...
2    [FOI_AGRICULTURE_FOOD|FOI_AF_FORESTRY, FOI_AGR...

其中第一元素是

['FOI_AGRICULTURE_FOOD|FOI_AF_FOOD_INDUSTRY', 'FOI_AGRICULTURE_FOOD|FOI_AF_FOOD_INDUSTRY']

使用result.groupby('id')['code'].agg(list).iloc[0]

相关问题