【问题标题】:Convert a key value pair in a column as new column in python将列中的键值对转换为python中的新列
【发布时间】:2021-04-23 19:32:27
【问题描述】:

我想解析一列,并将键值对作为列

输入:

我有一个具有以下结构的数据框(称为 df):

ID data
A1  {"userMatch": "{"match":{"phone":{"name":{"score":1}},"name":{"score":1}}}"}
A2  {"userMatch": "{"match":{"phone":{"name":{"score":0.934}},"name":{"score":0.952}}}"}

预期输出:

我想创建一个名为'score'的新列并从键值对中获取值

ID score1 score2
A1  1     1
A2  0.934 0.952

尝试的解决方案:

data_json = df['data'].transform(lambda x: json.loads(x))
df['score1'] = data_json.str.get('userMatch').str.get('match').str.get('phone').str.get('name').str.get('score')
df['score2'] = data_json.str.get('userMatch').str.get('match').str.get('phone').str.get('name').str.get('name').str.get('score')    

错误:

TypeError: the JSON object must be str, bytes or bytearray, not Series

注意事项:

我什至不确定如何获得下一个分数2

【问题讨论】:

  • 你为什么要做 data_json = df['data'].transform(lambda x: json.loads(x)).您已经阅读为 json。你试过没有它吗?
  • 你也可以发布数据类型吗?
  • 由于数据列似乎包含一个带有单个键 =“UserMatch”的字典和一个由字符串组成的单个值(即)"{"match":{"phone":{"name":{"score":1}},"name":{"score":1}}}",因此您可以使用正则表达式来解析得分值。
  • @Dieter yes,ID->字符串和数据->对象
  • @Epsi95 是的,我累了,收到错误消息“只能将 .str 访问器与字符串值一起使用!”

标签: json python-3.x pandas


【解决方案1】:

虽然关于使用正则表达式,但使用 mu previous,这就是我解决问题的方法:

import re
def getOffset(row, offset):
    vals = re.findall(r"[-+]?\d*\.\d+|\d+", row.data['userMatch'])
    if len(vals)> offset:
        return vals[offset]
    return None
df['score1'] = df.apply(lambda row: getOffset(row, 0), axis= 1)
df['score2'] = df.apply(lambda row: getOffset(row, 1), axis = 1)
df.drop(['data'], axis= 1, inplace=True)  

这会产生如下形式的数据框:

    ID  score1  score2
0   A1  1       1
1   A2  0.934   0.952

【讨论】:

    【解决方案2】:

    这并不漂亮,但适用于split()。无法读取字典,不断收到无效语法或缺少分隔符。

    df = pd.read_csv(io.StringIO('''ID  data
    A1  {"userMatch": "{"match":{"phone":{"name":{"score":1}},"name":{"score":1}}}"}
    A2  {"userMatch": "{"match":{"phone":{"name":{"score":0.934}},"name":{"score":0.952}}}"}'''), sep='  ', engine='python')
    
    df['score1'] = df['data'].apply(lambda x: x.split('{"userMatch": "{"match":{"phone":{"name":{"score":')[1].split('}', 1)[0])
    df['score2'] = df['data'].apply(lambda x: x.split('{"userMatch": "{"match":{"phone":{"name":{"score":')[1].split(',"name":{"score":')[1].split('}', 1)[0])
    

    输出:

       ID                                                                                  data score1 score2
    0  A1          {"userMatch": "{"match":{"phone":{"name":{"score":1}},"name":{"score":1}}}"}      1      1
    1  A2  {"userMatch": "{"match":{"phone":{"name":{"score":0.934}},"name":{"score":0.952}}}"}  0.934  0.952
    

    【讨论】:

      猜你喜欢
      • 2016-02-22
      • 2020-05-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-10
      • 2018-11-16
      相关资源
      最近更新 更多