基于 JSON 列表的肌酸新列

Posted

技术标签:

【中文标题】基于 JSON 列表的肌酸新列【英文标题】:Creatine New Column Based on JSON List 【发布时间】:2021-11-09 20:00:38 【问题描述】:

我有以下数据集。

                     details
USA     ['country': 'USA', 'city': 'NYC']
India   ['country': 'India', 'city': 'Mumbai']
Canada  ['country': 'Canada', 'city': 'VC']

我需要创建一个名为city 的新列。我正在尝试以下代码 sn-p 但发现 TypeError。

df['details'] = df['details'].str.strip('[]')
df['city'] = df['details'].map(lambda x: x['city'])
df
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-38-3f4a312e7420> in <module>
      1 df['details'] = df['details'].str.strip('[]')
----> 2 df['city'] = df['details'].map(lambda x: x['city'])
      3 df

/opt/anaconda3/lib/python3.8/site-packages/pandas/core/series.py in map(self, arg, na_action)
   3907         dtype: object
   3908         """
-> 3909         new_values = super()._map_values(arg, na_action=na_action)
   3910         return self._constructor(new_values, index=self.index).__finalize__(
   3911             self, method="map"

/opt/anaconda3/lib/python3.8/site-packages/pandas/core/base.py in _map_values(self, mapper, na_action)
    935 
    936         # mapper is a function
--> 937         new_values = map_f(values, mapper)
    938 
    939         return new_values

pandas/_libs/lib.pyx in pandas._libs.lib.map_infer()

<ipython-input-38-3f4a312e7420> in <lambda>(x)
      1 df['details'] = df['details'].str.strip('[]')
----> 2 df['city'] = df['details'].map(lambda x: x['city'])
      3 df

TypeError: string indices must be integers

我觉得我面临的问题是数据类型。理想的做法是什么?

任何建议将不胜感激。谢谢!

【问题讨论】:

【参考方案1】:

details 列的数据类型是str 类型,而不是dict 类型。这里需要做的是首先需要通过json.loads解析details列,然后可以通过city键获取值。

您需要将单引号替换为双引号才能正常工作。

In [5]: df["details"].apply(lambda x: json.loads(x.replace("'", '"'))["city"])
Out[5]:
0    NYC
Name: details, dtype: object```

【讨论】:

嗨@faraz-mazhar,谢谢你的帮助。发现这个错误:JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 3 (char 2) @Roy 您需要用答案中提到的双引号替换单引号。我已经更新了我的代码块以显示这一点。【参考方案2】:

试试下面的代码

展开列表,然后尝试访问城市。

df['city'] = df['details'].explode().map(lambda x: x['city'])

不要剥离使用:df['details'] = df['details'].str.strip('[]') 而是使用[explode()],如上面的代码所示

【讨论】:

以上是关于基于 JSON 列表的肌酸新列的主要内容,如果未能解决你的问题,请参考以下文章

Fitness.各类补剂的使用指南(摘自知乎:黄啸)

PySpark Dataframe 将两列转换为基于第三列值的元组新列

基于小波变换的EMG信号病人数据matlab仿真分析

Dask 基于上一列添加新列

在 Spark 中基于窗口和条件创建新列

基于字典键创建具有值的新列