Встроенный метод объектов .size()
объектов DataFrameGroupBy фактически возвращает объект Series с размерами группы, а не DataFrame. Если вы хотите, чтобы DataFrame, чей столбец был размером группы, индексированный группами, с настраиваемым именем, вы можете использовать метод .to_frame()
и использовать в качестве аргумента имя требуемого столбца.
grpd = df.groupby(['A','B']).size().to_frame('size')
Если вы хотите, чтобы группы были столбцами снова, вы могли бы добавить .reset_index()
в конец.
var jsonData1 = [{firstName: "Sam",age: "10"},{firstName: "John",age: "11"},{firstName: "Jack",age: "12"},{firstName: "Pam",age: "13"},{firstName: "Tom",age: "14"},{firstName: "Mitch",age: "15"}];
var jsonData2 = [{firstName: "Sam",city: "London"},{firstName: "John",city: "New York"},{firstName: "Jack",city: "Paris"},{firstName: "Pam",city: "Moscow"},{firstName: "Roger",city: "Shanghai"},{firstName: "Don",city: "Jakarta"}];
var defaults = {firstName: "", age: "", city: ""};
var data = [ ...jsonData1, ...jsonData2 ];
var names = [ ...new Set(data.map(i=>i.firstName)) ];
var res = names.map(n => data
.reduce((acc, jd) => jd.firstName === n ? {...acc, ...jd} : acc, defaults)
);
console.log(res);
var data
объединяет два массива данных в один, используя синтаксис расширения (литералы массива) ) SUP>.
var names
создает массив уникальных имен, используя Set
.
map()
перебирает список имен, создавая один объединенный объект для каждого. Это объединение выполняется с использованием reduce()
и расширенного синтаксиса (литералы объекта) sup>.
Есть несколько способов приблизиться к этому, однако один из вариантов будет основывать это на методе Array#reduce()
следующим образом:
const jsonData1=[{firstName:"Sam",age:"10"},{firstName:"John",age:"11"},{firstName:"Jack",age:"12"},{firstName:"Pam",age:"13"},{firstName:"Tom",age:"14"},{firstName:"Mitch",age:"15"}];
const jsonData2=[{firstName:"Sam",city:"London"},{firstName:"John",city:"New York"},{firstName:"Jack",city:"Paris"},{firstName:"Pam",city:"Moscow"},{firstName:"Roger",city:"Shanghai"},{firstName:"Don",city:"Jakarta"}];
/*
Use Array#concat() to combine both input arrays before performing
the merge. This will ensure that all items in both arrays are
processed and accounted for during the merge (which is important in
situations where the input arrays differ in length).
Object.values() is used to transform the dictionary resulting from
reduce() to an array
*/
var result = Object.values(
[].concat(jsonData1, jsonData2
).reduce((dict, item) => {
/*
We use Array#reduce is an intermediate step to construct a dictionary
which maps each unique "item.firstName" to a corresponding object
that contains the merged (or yet to be merged) data for this first
name
*/
var value = dict[item.firstName] || {}
/*
Use Object.assign() to merge existing data for "item.firstName" with
current item being processed. Also pass default values as first
argument to ensure all three key values are present in merge result
*/
value = Object.assign({ firstName : '', age : '', city : ''} , value, item)
/*
Update the dictionary with merged data
*/
dict[item.firstName] = value
return dict
}, {}))
console.log(result);
Один из возможных подходов:
const jsonData1=[{firstName:"Sam",age:"10"},{firstName:"John",age:"11"},{firstName:"Jack",age:"12"},{firstName:"Pam",age:"13"},{firstName:"Tom",age:"14"},{firstName:"Mitch",age:"15"}];
const jsonData2=[{firstName:"Sam",city:"London"},{firstName:"John",city:"New York"},{firstName:"Jack",city:"Paris"},{firstName:"Pam",city:"Moscow"},{firstName:"Roger",city:"Shanghai"},{firstName:"Don",city:"Jakarta"}];
const result = [].concat(jsonData1, jsonData2).reduce((acc, ele) => {
const existing = acc.find(x => x.firstName === ele.firstName);
if(!existing) return acc.concat({firstName: ele.firstName, city: ele.city || '', age: ele.age || ''});
Object.keys(ele).forEach(x => existing[x] = ele[x]);
return acc;
},[])
console.log(result);