我想将嵌套的json转换为csv文件。
我正在从Rest API接收json。
csv中的字段应如下所示。
daterange_start,daterange_end,点击次数,展示次数,数据透视值。
我是Python和JSON的新手,所以希望获得一些帮助。
这是示例json。
HERE is my KO.JS
```````````````````````````````````````````
// Declare function contain object info as a storage for json items
function locationInfo(info) {
var self = this;
self.name = info.name;
self.location = info.location;
self.photo = info.photos;
self.contact = info.contact;
self.id = info.id;
self.categories = info.categories;
self.address = info.location.formattedAddress;
}
function ViewModel() {
var self = this;
// Constructor creates a new map - only center and zoom are defined.
self.map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 32.7761827, lng: -96.7995296},
zoom: 11
});
/*
self.infowindow = new google.maps.InfoWindow({
content: document.getElementById('popupinfo')
});
*/
// declare infowindow instances **
self.largeInfowindow = new google.maps.InfoWindow();
self.bounds = new google.maps.LatLngBounds();
//
autocomplete = new google.maps.places.Autocomplete((document.getElementById('places-search')),
{
types: ['(cities)']
}
);
self.places = new google.maps.places.PlacesService(self.map);
google.maps.event.addListener(autocomplete, 'place_changed', searchBoxPlaces);
// Using google street view
self.streetViewService = new google.maps.StreetViewService();
// defined radius for 50 miles
self. radius = 50;
// define the location array using knockout observable array
self.locations = ko.observableArray([]);
// define markers for each location using knockout obseravble array
self.markers = ko.observableArray([]);
// define filter input text using knockout observable function
self.filter = ko.observable();
// self.cityName = document.getElementById('places-search').value;
function searchBoxPlaces() {
self.place = autocomplete.getPlace();
if (self.place.length == 0) {
window.alert('We did not find any places matching that search!');
} else {
// For each place, get the icon, name and location.
self.map.panTo(self.place.geometry.location);
self.map.setZoom(13);
}
self.cityName = self.place.address_components[0].long_name;
//console.log(self.cityName);
self.url = "https://api.foursquare.com/v2/venues/search?client_id=NQM5SU1P2NFO2T05ICZFQBZDSZPHOGEDSSY2ABR4YOL1BZ43&client_secret=2ESR3ZZPIGATWXAIZ4UF5P2EPHHAITWVA4WEWYLNEGRINBRE&v=20180323&limit=5&near=" + self.cityName + "&query=bank";
// getJson information from foursquare api
$.getJSON(self.url, function(data) {
// listLocation will hold the array value of
//each mapped object and its object property value >>(function items)
let listLocations = $.map(data.response.venues, function(items){
return new locationInfo(items);
//console.log(locationInfo);
});
//using knock out to store locations
self.locations(listLocations);
//console.log(self.locations);
}).error ( function (e){
$(".bank-list").hide();
$(".locationsErrorHandling").show();
});
}
// Create marker Object function which we will pass in a knockout location array property
// when function is called to create a marker object location
self.markerOjbectCreated = function (location){
let marker = new google.maps.Marker({
map: self.map,
position: location.location,
title: location.name,
id: location.id,
desc: location.desc,
animation: google.maps.Animation.Drop,
display: location.display
});
return marker;
};
// creating object function allows to binding between the list and pop up info window
self.selectedLocation = function (clickedLocation){
if ( clickedLocation instanceof locationInfo) {
for ( let i = 0; i < self.markers().length; i++){
// if the clicked name is matching with marker name then set it to marker
if (clickedLocation.name = self.markers()[i].name){
clickedLocation = self.markers()[i];
}
}
}
// Force marker unbounce
self.toggleUnbounce(self.markers());
//Marker bounce when venues's name clicked
self.toggleBounce(clickedLocation);
// Then popup window will opened up
self.populateInfoWindow(clickedLocation, self.largeInfowindow);
};
// comparing strings object function
self.stringStartWith = function ( string, startsWith){
string = string || "";
if (startsWith.length > string.length)
return false;
else
return string.substring(0,startsWith.length) == startsWith;
};
// Populate markers on map with this OF
self.displayMarkersLocation = function (markers) {
//console.log(markers);
for (let i = 0; i < markers.length; i++){
markers[i].setMap(self.map);
self.bounds.extend(markers[i].position);
}
self.map.fitBounds(self.bounds);
};
// clear marker before search marker pop up
self.clearMarkers = function(markers) {
for (var i = 0; i < self.markers.length; i++) {
if (markers[i]) {
markers[i].setMap(null);
}
}
self.markers = [];
};
// show markers
self.showMarker = function ( marker) {
marker.setMap(self.map);
self.bounds.extend(marker.position);
self.map.fitBounds(self.bounds);
};
// Hide markers
self.hideMarkers = function ( markers) {
for (let i = 0; i < markers.length; i++){
markers[i].setMap(null);
}
};
// Filter text items
self.filteredBank = ko.computed( function(){
let filter = self.filter();
let startsWith = false;
if (!filter) {
self.displayMarkersLocation(self.markers());
return self.locations();
}else {
self.hideMarkers(self.markers());
return ko.utils.arrayFilter(self.markers(), function(marker){
startsWith = marker.title.toLowerCase().indexOf(filter.toLowerCase()) !==-1;
if (startsWith){
self.showMarker(marker);
return true;
}
});
}
}, self);
// Marker Bouncing Function
self.toggleBounce = function (marker){
if(marker.getAnimation() !== null){
marker.setAnimation(null);
} else {
marker.setAnimation(google.maps.Animation.BOUNCE);
}
};
// Marker unbounce Function
self.toggleUnbounce = function (markers){
for ( let i = 0; i < markers.length; i++){
if (markers[i].getAnimation() !== null){
markers[i].setAnimation(null);
}
}
};
self.populateInfoWindow = function (marker, infowindow){
// first we need to check to make sure the infowindow is not already opened on this marker.
if (infowindow.marker != marker){ // if info window not set to marker then
infowindow.setContent(''); // then use setContent function to html div and pass in marker title
infowindow.marker = marker; // set infowindow marker to marker
// then use open method to open it
// make sure the marker property is cleared if the infowindow is closed.
// why? is it going to display on next window?
infowindow.addListener('closeclick', function(){
self.toggleUnbounce(self.markers());
infowindow.setMarker = null; // using setMarker function to null to clear marker info.
});
// we need to instancitate the streetViewService method from google maps
// if we can't find exact location then define radius of 50 meter nearby area
let streetViewService = new google.maps.StreetViewService();
let radius = 50;
// In case the status is OK, which means the pano was found, compute the
// position of the streetview image, then calculate the heading, then get a
// panorama from that and set the options
let getStreetView = function(data, status) {
if (status == google.maps.StreetViewStatus.OK) {
let nearStreetViewLocation = data.location.latLng; // load geometry library
let heading = google.maps.geometry.spherical.computeHeading(
nearStreetViewLocation, marker.position);
infowindow.setContent('<div>'+ '<h3>' + marker.title + '</h3>' + '</div>' +
'<div id="pano"></div>' + '<div>' + '<p>' + marker.address + '</p>' +
'<p>' + marker.desc + '</p>' + '</div>' );
let panoramaOptions = { // set panarama option
position: nearStreetViewLocation,
pov: {
heading: heading,
pitch: 30
}
};
let panorama = new google.maps.StreetViewPanorama( // create panarama image and pass it into id pano
document.getElementById('pano'), panoramaOptions);
}
else {
infowindow.setContent('<div>'+ '<h3>' + marker.title + '</h3>' + '</div>' +
'<div>No Street View Found</div>');
}
};
// Use streetview service to get the closest streetview image within
// 50 meters of the markers position, pass into this function with marker position
// radius and function getStreetView to the getPanoramaByLocation function.
self.streetViewService.getPanoramaByLocation(marker.position, self.radius, getStreetView);
// Open the infowindow on the correct marker.
infowindow.open(self.map, marker);
}
};
self.mapLoading = ko.computed (function () {
let locations = self.locations();
//console.log(locations);
//let markers = self.markers();
//console.log(markers);
let largeInfowindow = self.largeInfowindow;
let bounds = self.bounds;
let clickMarkerWindow = function ( marker, largeInfowindow){
marker.addListener('click', function () {
self.toggleUnbounce(self.markers());
self.toggleBounce( this);
self.populateInfoWindow(this, largeInfowindow);
});
};
// now we use knock out array to create array when the map is loading
for (let i = 0; i < locations.length; i++){
let marker = self.markerOjbectCreated(locations[i]);
// store markers in knockout marker arrray
self.markers().push(marker);
// allow popup window to open when marker is clicking with OF defined aboveed
clickMarkerWindow(marker, largeInfowindow);
// recenter bound map to that location
bounds.extend(self.markers()[i].position);
} // End of forloop
// Extend map to cover all markers
self.map.fitBounds(bounds);
$(window).resize(function() {
google.maps.event.addDomListener(window, 'resize', function() {
self.map.fitBounds(bounds);
});
});
}, self);
// call maploading object.
self.mapLoading();
}
// Call back funtion to load initMap
function initMap() {
ko.applyBindings( new ViewModel() );
}
答案 0 :(得分:1)
您可以使用以下命令在python中加载并解析json:
import json
y = json.loads(x)
y
将是python字典。现在,在y['elements']
上循环并创建一个包含所需字段的列表。例如,提取开始日期和结束日期的年份:
list_for_csv=[]
for e in y['elements']:
list_for_csv.append([e['daterange']['start']['year'],e['daterange']['end']['year']])
然后使用numpy将其另存为csv:
import numpy as np
for_csv = np.asarray(list_for_csv)
np.savetxt("your_file.csv", for_csv, delimiter=",")
答案 1 :(得分:1)
您可以使用json_normalize
。唯一的问题是"pivotValues"
是一个列表。因此,不确定要在那里保存的内容,或者这些列表中是否包含1个以上的元素。如果只是一个元素,则可以轻松地处理该列。如果它可以包含多个元素,则可以为每个元素创建一个新行(这意味着您有多个具有相同数据的行,但不同的pivotValues
除外,也可以扩展每一行以使每个pivotValues
,但这些列表的长度为null时长度会不同。
我还在那里添加了代码(看到pivotValues
都具有相同的前缀),以防您需要帽子值。
给出:
data = {
"elements": [
{
"dateRange": {
"start": {
"month": 3,
"year": 2019,
"day": 3
},
"end": {
"month": 3,
"year": 2019,
"day": 3
}
},
"clicks": 11,
"impressions": 2453,
"pivotValues": [
"urn:li:sponsoredCampaign:1234567"
]
},
{
"dateRange": {
"start": {
"month": 3,
"year": 2019,
"day": 7
},
"end": {
"month": 3,
"year": 2019,
"day": 7
}
},
"clicks": 1,
"impressions": 629,
"pivotValues": [
"urn:li:sponsoredCampaign:1234565"
]
},
{
"dateRange": {
"start": {
"month": 3,
"year": 2019,
"day": 21
},
"end": {
"month": 3,
"year": 2019,
"day": 21
}
},
"clicks": 3,
"impressions": 154,
"pivotValues": [
"urn:li:sponsoredCampaign:1323516"
]
}
],
"paging": {
"count": 10,
"start": 0,
"links": []
}
}
代码:
import pandas as pd
from pandas.io.json import json_normalize
df = json_normalize(data['elements'])
df['pivotValues'] = df.pivotValues.apply(pd.Series).add_prefix('pivotValues_')
df['pivotValues_stripped'] = df['pivotValues'].str.rsplit(':',1, expand=True)[1]
df.to_csv('path/filename.csv', index=False)
输出:
print (results.to_string())
clicks dateRange.end.day dateRange.end.month dateRange.end.year dateRange.start.day dateRange.start.month dateRange.start.year impressions pivotValues pivotValues_stripped
0 11 3 3 2019 3 3 2019 2453 urn:li:sponsoredCampaign:1234567 1234567
1 1 7 3 2019 7 3 2019 629 urn:li:sponsoredCampaign:1234565 1234565
2 3 21 3 2019 21 3 2019 154 urn:li:sponsoredCampaign:1323516 1323516