После выгрузки данных пять разных записей могут оказаться в одной категории «пусто», если смотреть только на истинность значения. Для исследовательского набора это рискованно: отсутствие ключа и известный ноль обозначают разные состояния. Разберём представление, не гадая, почему ответ не был записан.

Это авторский учебный набор из пяти вымышленных объектов A01, A02, A03, A04 и A05. Поле value намеренно содержит разные типы, чтобы показать диагностику. Мы не утверждаем, что такой смешанный столбец допустим в реальном проекте. Задача в том, чтобы сохранить различия при чтении JSON, а затем сверить их с описанием данных.

Пять записей и пять состояний

Учебная запись

   

Что в ней записано

A01: только id

   

Ключ value отсутствует.

A02: value равен null

   

Ключ есть, его значение равно JSON null.

A03: value равен false

   

Ключ есть, значение логическое false.

A04: value равен 0

   

Ключ есть, значение равно целому числу 0.

A05: value равен ""

   

Ключ есть, значение равно пустой строке.

Учебная схема пяти JSON-объектов: отсутствие ключа, null, false, 0 и пустая строка получают разные диагностические статусы; по 1 объекту каждого вида.
Авторская учебная схема, все пять объектов вымышлены. Статусы различают представление и тип, не устанавливают причины отсутствия ответа и не назначают допустимые значения реального исследования.

В таблице преобразований json.loads null соответствует None, false — False, а целое JSON-число — int. В документации стандартных типов Python описаны проверка истинности и принадлежность bool к подклассам int. Поэтому порядок и точность проверок здесь существенны.

Полный код диагностики без замены исходных значений

import json

text = """[
  {"id":"A01"},
  {"id":"A02","value":null},
  {"id":"A03","value":false},
  {"id":"A04","value":0},
  {"id":"A05","value":""}
]"""
rows = json.loads(text)

def diagnose(row):
    if "value" not in row:
        return "absent"
    value = row["value"]
    if value is None:
        return "null"
    if type(value) is bool:
        return "boolean"
    if type(value) is int and value == 0:
        return "integer_zero"
    if isinstance(value, str) and value == "":
        return "empty_string"
    return "other"

statuses = [diagnose(row) for row in rows]
for row, status in zip(rows, statuses):
    print(row["id"], status)
print("records =", len(rows))
print("distinct_statuses =", len(set(statuses)))
assert statuses == ["absent", "null", "boolean",
                    "integer_zero", "empty_string"]
assert all(not row.get("value") for row in rows)

Вывод для приведённого учебного примера:

A01 absent
A02 null
A03 boolean
A04 integer_zero
A05 empty_string
records = 5
distinct_statuses = 5

Набор rows сохраняется; функция возвращает отдельный диагностический статус. Ровно один объект попал в каждую из пяти категорий. Названия статусов выбраны автором для упражнения. Они описывают представление и тип, а не объясняют, почему человек не ответил или почему система не передала поле.

Где теряются различия

Проверка или преобразование

   

Почему нужно уточнить правило

if not row.get("value")

   

В нашем наборе условие истинно для всех пяти объектов: различия исчезнут.

row.get("value") без отдельного контроля ключа

   

Для A01 и A02 результатом будет None, и так не отличить отсутствие ключа от null.

value == 0 до проверки типа

   

В Python False == 0 истинно, но совпадение значения не означает одинаковый тип.

Заменить любое «пустое» значение нулём

   

Это добавит числовые значения, которых исходная выгрузка не содержала.

В коде сначала проверяется наличие ключа, затем None, затем точный тип bool. Только после этого отдельно рассматривается целочисленный ноль. Конструкция type(value) is int намеренно выбрана вместо isinstance(value, int), потому что bool является подклассом int. Проверка пустой строки выполняется среди строк. Другие значения возвращают other, и для них показанная диагностическая схема не задаёт дальнейшей обработки.

Как перейти от диагностики к анализу

  • Сохраните исходный JSON и ID, а статусы запишите в отдельное поле.
  • Сверьте документацию источника: обязательно ли поле и какие типы в нём разрешены.
  • Уточните значение null: код сам не устанавливает отказ, неприменимость или технический сбой.
  • Проверьте смысл false, числового нуля и пустого текста для своей переменной.
  • После согласования правил отдельно подсчитайте категории и только затем формируйте аналитический столбец.

Здесь нет среднего или процента ответивших: учебный набор специально смешивает типы и не задаёт аналитическую переменную. Мы проверили лишь пять объектов и пять диагностических состояний. Переход от состояния к пропуску, отказу или осмысленному значению должен опираться на правила проекта, а не на bool(value).

Методическая связь с кодировочной книгой анкеты такова: описание переменной должно объяснять её допустимые значения и пропуски. Данная инструкция решает более узкую техническую задачу — сохраняет различия представления в JSON до содержательного кодирования. Она не заменяет схему данных и не проверяет корректность произвольных вложенных документов.

Если требуется подготовить собственную выгрузку к исследовательскому расчёту, можно обсудить консультацию по статистическому анализу. Заранее согласуйте исследовательский вопрос, структуру исходного файла и объём помощи. Успешное чтение файла само по себе не подтверждает достоверность измерений.