DataFrame: also filter fields in single frame case in outerJoinDataFrames() (#33343)

This commit is contained in:
Leon Sorokin 2021-04-23 21:28:18 -05:00 committed by GitHub
parent 693915de35
commit 47e68580a6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 11 deletions

View File

@ -71,13 +71,15 @@ function getJoinMatcher(options: JoinOptions): FieldMatcher {
*/ */
export function outerJoinDataFrames(options: JoinOptions): DataFrame | undefined { export function outerJoinDataFrames(options: JoinOptions): DataFrame | undefined {
if (!options.frames?.length) { if (!options.frames?.length) {
return undefined; return;
} }
if (options.frames.length === 1) { if (options.frames.length === 1) {
let frame = options.frames[0]; let frame = options.frames[0];
let frameCopy = frame;
if (options.keepOriginIndices) { if (options.keepOriginIndices) {
frame = { frameCopy = {
...frame, ...frame,
fields: frame.fields.map((f, fieldIndex) => { fields: frame.fields.map((f, fieldIndex) => {
const copy = { ...f }; const copy = { ...f };
@ -94,16 +96,35 @@ export function outerJoinDataFrames(options: JoinOptions): DataFrame | undefined
}), }),
}; };
} }
const joinFieldMatcher = getJoinMatcher(options);
const joinIndex = frameCopy.fields.findIndex((f) => joinFieldMatcher(f, frameCopy, options.frames));
if (options.enforceSort) { if (options.enforceSort) {
const joinFieldMatcher = getJoinMatcher(options);
const joinIndex = frame.fields.findIndex((f) => joinFieldMatcher(f, frame, options.frames));
if (joinIndex >= 0) { if (joinIndex >= 0) {
if (!isLikelyAscendingVector(frame.fields[joinIndex].values)) { if (!isLikelyAscendingVector(frameCopy.fields[joinIndex].values)) {
return sortDataFrame(frame, joinIndex); frameCopy = sortDataFrame(frameCopy, joinIndex);
} }
} }
} }
return frame;
if (options.keep) {
let fields = frameCopy.fields.filter(
(f, fieldIdx) => fieldIdx === joinIndex || options.keep!(f, frameCopy, options.frames)
);
// mutate already copied frame
if (frame !== frameCopy) {
frameCopy.fields = fields;
} else {
frameCopy = {
...frame,
fields,
};
}
}
return frameCopy;
} }
const nullModes: JoinNullMode[][] = []; const nullModes: JoinNullMode[][] = [];

View File

@ -34,7 +34,6 @@ export function buildPlotConfig(props: PlotProps, plugins: Record<string, PlotPl
} }
/** @internal */ /** @internal */
export function preparePlotData(frame: DataFrame, keepFieldTypes?: FieldType[]): AlignedData { export function preparePlotData(frame: DataFrame, keepFieldTypes?: FieldType[]): AlignedData {
const result: any[] = []; const result: any[] = [];
const stackingGroups: Map<string, number[]> = new Map(); const stackingGroups: Map<string, number[]> = new Map();
@ -57,9 +56,11 @@ export function preparePlotData(frame: DataFrame, keepFieldTypes?: FieldType[]):
seriesIndex++; seriesIndex++;
continue; continue;
} }
if (keepFieldTypes && keepFieldTypes.indexOf(f.type) < 0) { if (keepFieldTypes && keepFieldTypes.indexOf(f.type) < 0) {
continue; continue;
} }
collectStackingGroups(f, stackingGroups, seriesIndex); collectStackingGroups(f, stackingGroups, seriesIndex);
result.push(f.values.toArray()); result.push(f.values.toArray());
seriesIndex++; seriesIndex++;
@ -70,18 +71,20 @@ export function preparePlotData(frame: DataFrame, keepFieldTypes?: FieldType[]):
// array or stacking groups // array or stacking groups
for (const [_, seriesIdxs] of stackingGroups.entries()) { for (const [_, seriesIdxs] of stackingGroups.entries()) {
const acc = Array(result[0].length).fill(0); const acc = Array(result[0].length).fill(0);
for (let j = 0; j < seriesIdxs.length; j++) { for (let j = 0; j < seriesIdxs.length; j++) {
const currentlyStacking = result[seriesIdxs[j]]; const currentlyStacking = result[seriesIdxs[j]];
for (let k = 0; k < result[0].length; k++) { for (let k = 0; k < result[0].length; k++) {
const v = currentlyStacking[k]; const v = currentlyStacking[k];
acc[k] += v === null || v === undefined ? 0 : +v; acc[k] += v == null ? 0 : +v;
} }
result[seriesIdxs[j]] = acc.slice(); result[seriesIdxs[j]] = acc.slice();
} }
} }
return result as AlignedData;
} }
return result as AlignedData; return result as AlignedData;
} }