Зацикливание данных JSON динамически в Python - PullRequest
0 голосов
/ 29 августа 2018

У меня есть два файла JSON на сервере. Первый файл json представляет собой фрейм данных в формате json, в котором он содержит 21 столбец.

Второй объект json - это набор различных фильтров, которые должны быть применены к первому json (файл данных), и я хочу динамически рассчитать уменьшение столбца количества после применения каждого фильтра.

Оба jsons находятся на сервере. Пример этого, как показано ниже,

[{
        "criteria_no.": 1,
        "expression": "!=",
        "attributes": "Industry_name",
        "value": "Clasentrix"

    },{ 
        "criteria_no.": 2,
        "expression": "=",
        "attributes": "currency",
        "value": ["EUR","GBP","INR"]


    },{
        "criteria_no.": 3,
        "expression": ">",
        "attributes": "Industry_Rating",
        "value": "A3"

    },{
        "criteria_no.": 4,
        "expression": "<",
        "attributes": "Due_date",
        "value": "01/01/2025"

    }
    ]

При кодировании на python, это как ниже,

import urllib2, json
url = urllib2.urlopen('http://.../server/criteria_sample.json')
obj = json.load(url)
print obj

[{u'attributes': u'Industry_name', u'expression': u'!=', u'value': u'Clasentrix', u'criteria_no.': 1}, {u'attributes': u'currency', u'expression': u'=', u'value': [u'EUR', u'GBP', u'INR'], u'criteria_no.': 2}, {u'attributes': u'Industry_Rating', u'expression': u'>', u'value': u'A3', u'criteria_no.': 3}, {u'attributes': u'Due_date', u'expression': u'<', u'value': u'01/01/2025', u'criteria_no.': 4}]

Теперь в примере json мы видим "attributes", которые представляют собой не что иное, как столбцы, присутствующие в первом файле данных. Я упоминал, что у него есть 21 столбец, "Industry_name", "currency", "Industry_Rating", "Due_date" - четыре из них. "Loan_amount" - это еще один столбец в файле данных вместе со всеми ними.

Теперь, поскольку этот список критериев является только образцом, у нас есть n таких критериев или фильтров. Я хочу, чтобы эти фильтры динамически применялись к файлу данных, и я хотел бы рассчитать уменьшение суммы кредита. Давайте рассмотрим первый фильтр, он говорит, что столбец "Industry_name" не должен иметь "Clasentrix". Поэтому из файла данных я хочу отфильтровать "Industry_name", в котором не будет записи 'Clasentrix'. Теперь, скажем, для 11 наблюдений у нас было 'Clasentrix' из 61 наблюдения из файла данных. Затем мы возьмем сумму всей суммы кредита (61 строка) и затем вычтем сумму суммы кредита для 11 строк, которые составляют 'Clasentrix' из общей суммы кредита. Это число будет считаться уменьшением после применения первого фильтра.

Теперь для каждого из n критериев я хочу динамически рассчитать уменьшение в python. Таким образом, внутри цикла JSON-файл фильтра создаст фильтр с учетом атрибута, выражения и значения. Как и для первого фильтра, это "Industry_name != 'Clasentrix'". Это должно отражаться для каждого набора строк для объекта json, как и для второго критерия (фильтра), это должно быть "currency=['EUR','GBP','INR']" и так далее. Я также хочу рассчитать сокращение соответственно.

Я изо всех сил пытаюсь создать код Python для вышеупомянутого упражнения. Мой пост слишком длинный, извиняюсь за это. Но, пожалуйста, помогите, как я могу рассчитать сокращение динамически для каждого критерия n.

Заранее спасибо !!

ОБНОВЛЕНИЕ для первого файла данных, найдите несколько строк образца;

[{
        "industry_id.": 1234,
        "loan_id": 1113456,
        "Industry_name": "Clasentrix",
        "currency": "EUR",
        "Industry_Rating": "Ba3",
        "Due_date": "20/02/2020",
        "loan_amount": 563332790,
        "currency_rate": 0.67,
        "country": "USA"


    },{ 
        "industry_id.": 6543,
        "loan_id": 1125678,
        "Industry_name": "Wolver",
        "currency": "GBP",
        "Industry_Rating": "Aa3",
        "Due_date": "23/05/2020",
        "loan_amount": 33459087,
        "currency_rate": 0.8,
        "country": "UK"


    },{
        "industry_id.": 1469,
        "loan_id": "8876548",
        "Industry_name": "GroupOn",
        "currency": "EUR",
        "Industry_Rating": "Aa1",
        "Due_date": "16/09/2021",
        "loan_amount": 66543278,
        "currency_rate": 0.67,
        "country": "UK"
    },{
        "industry_id.": 1657,
        "loan_id": "6654321",
        "Industry_name": "Clasentrix",
        "currency": "EUR",
        "Industry_Rating": "Ba3",
        "Due_date": "15/07/2020",
        "loan_amount": 5439908765,
        "currency_rate": 0.53,
        "country": "USA"

    }
    ] 

1 Ответ

0 голосов
/ 29 августа 2018

Вы можете использовать Pandas, чтобы превратить данные json в фрейм данных и превратить критерии в строки query. Некоторая обработка необходима, чтобы превратить критерии json в действительный запрос. В приведенном ниже коде даты по-прежнему обрабатываются как строки - вам может понадобиться явно установить запросы даты, чтобы сначала преобразовать строку в дату.

import pandas as pd
import json
# ...
criteria = json.load(url)
df = pd.DataFrame(json.load(data_url)) # data_url is the handle of the data file
print("Loan total without filters is {}".format(df["loan_amount"].sum()))

for c in criteria:
    if c["expression"] == "=":
        c["expression"] = "=="

    # If the value is a string we need to surround it in quotation marks
    # Note this can break if any values contain "
    if isinstance(c["value"], basestring):
        query = '{attributes} {expression} "{value}"'.format(**c)
    else:
        query = '{attributes} {expression} {value}'.format(**c)
    loan_total = df.query(query)["loan_amount"].sum()
    print "With criterion {}, {}, loan total is {}".format(c["criteria_no."], query, loan_total)

В качестве альтернативы вы можете превратить каждый критерий в индексный вектор следующим образом:

def criterion_filter(s, expression, value):
    if type(value) is list:
        if expression == "=":
            return s.isin(value)
        elif expression == "!=":
            return ~s.isin(value)
    else:
        if expression == "=":
            return s == value
        elif expression == "!=":
            return s != value
        elif expression == "<":
            return s < value
        elif expression == ">":
            return s > value        

for c in criteria:
    filt = criterion_filter(df[c["attributes"]], c["expression"], c["value"])
    loan_total = df[filt]["loan_amount"].sum()
    print "With criterion {}, loan total is {}".format(c["criteria_no."],  loan_total)

РЕДАКТИРОВАТЬ: Чтобы рассчитать совокупное сокращение общей суммы кредита, вы можете объединить векторы индексации с помощью оператора &.

loans = [df["loan_amount"].sum()]
print("Loan total without filters is {}".format(loans[0]))
filt = True
for c in criteria:
    filt &= criterion_filter(df[c["attributes"]], c["expression"], c["value"])
    loans.append(df[filt]["loan_amount"].sum())
    print "Adding criterion {} reduces the total by {}".format(c["criteria_no."],
        loans[-2] - loans[-1])
    print "The cumulative reduction is {}".format(loans[0] - loans[-1])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...