#python #pandas #csv
#python #pandas #csv
Вопрос:
Я пытался следовать нескольким ответам, которые я видел на SO, но я действительно застрял здесь. Я пытаюсь преобразовать CSV в JSON.
Схема JSON имеет несколько уровней вложенности, и некоторые значения в CSV будут общими.
Вот ссылка на одну запись в CSV.
Представьте этот пример как две разные стороны, прикрепленные к одному документу.
Поля в документе (document_source_id, document_amount, record_date, source_url, document_file_url, document _ type__title, apn, situs_county_id, state_code) не должны дублироваться.
При этом поля каждого объекта уникальны.
Я пытался вложить их, используя сложную инструкцию groupby, но застрял в получении данных в моей схеме.
Вот что я пробовал. Он не содержит всех полей, потому что мне трудно понять, что все это значит.
j = (df.groupby(['state_code',
'record_date',
'situs_county_id',
'document_type__title',
'document_file_url',
'document_amount',
'source_url'], as_index=False)
.apply(lambda x: x[['source_url']].to_dict('r'))
.reset_index()
.rename(columns={0:'metadata', 1:'parcels'})
.to_json(orient='records'))
Вот как должен выводиться пример CSV
{
"metadata":{
"source_url":"https://a836-acris.nyc.gov/DS/DocumentSearch/DocumentDetail?doc_id=2019012901225004",
"document_file_url":"https://a836-acris.nyc.gov/DS/DocumentSearch/DocumentImageView?doc_id=2019012901225004"
},
"state_code":"NY",
"nested_data":{
"parcels":[
{
"apn":"3972-61",
"situs_county_id":"36005"
}
],
"participants":[
{
"entity":{
"name":"5 AIF WILLOW, LLC",
"situs_street":"19800 MACARTHUR BLVD",
"situs_city":"IRVINE",
"situs_unit":"SUITE 1150",
"state_code":"CA",
"situs_zip":"92612"
},
"participation_type":"Grantee"
},
{
"entity":{
"name":"5 ARCH INCOME FUND 2, LLC",
"situs_street":"19800 MACARTHUR BLVD",
"situs_city":"IRVINE",
"situs_unit":"SUITE 1150",
"state_code":"CA",
"situs_zip":"92612"
},
"participation_type":"Grantor"
}
]
},
"record_date":"01/31/2019",
"situs_county_id":"36005",
"document_source_id":"2019012901225004",
"document_type__title":"ASSIGNMENT, MORTGAGE"
}
Ответ №1:
Возможно, вам потребуется использовать функцию json_normalize из pandas.io.json
from pandas.io.json import json_normalize
import csv
li = []
with open('filename.csv', 'r') as f:
reader = csv.DictReader(csvfile)
for row in reader:
li.append(row)
df = json_normalize(li)
Здесь мы создаем список словарей из файла csv и фрейм данных с помощью функции json_normalize.
Ответ №2:
Ниже приведен один из способов экспорта ваших данных:
# all columns used in groupby()
grouped_cols = ['state_code', 'record_date', 'situs_county_id', 'document_source_id'
, 'document_type__title', 'source_url', 'document_file_url']
# adjust some column names to map to those in the 'entity' node in the desired JSON
situs_mapping = {
'street_number_street_name': 'situs_street'
, 'city_name': 'situs_city'
, 'unit': 'situs_unit'
, 'state_code': 'state_code'
, 'zipcode_full': 'situs_zip'
}
# define columns used for 'entity' node. python 2 need to adjust to the syntax
entity_cols = ['name', *situs_mapping.values()]
#below for python 2#
#entity_cols = ['name'] list(situs_mapping.values())
# specify output fields
output_cols = ['metadata','state_code','nested_data','record_date'
, 'situs_county_id', 'document_source_id', 'document_type__title']
# define a function to get nested_data
def get_nested_data(d):
return {
'parcels': d[['apn', 'situs_county_id']].drop_duplicates().to_dict('r')
, 'participants': d[['entity', 'participation_type']].to_dict('r')
}
j = (df.rename(columns=situs_mapping)
.assign(entity=lambda x: x[entity_cols].to_dict('r'))
.groupby(grouped_cols)
.apply(get_nested_data)
.reset_index()
.rename(columns={0:'nested_data'})
.assign(metadata=lambda x: x[['source_url', 'document_file_url']].to_dict('r'))[output_cols]
.to_json(orient="records")
)
print(j)
Примечание: Если participants
содержат дубликаты и должны выполняться drop_duplicates(), как мы делаем на parcels
, тогда assign(entity
) можно перейти к определению participants
в get_nested_data()
функции:
, 'participants': d[['participation_type', *entity_cols]]
.drop_duplicates()
.assign(entity=lambda x: x[entity_cols].to_dict('r'))
.loc[:,['entity', 'participation_type']]
.to_dict('r')