Populate a single array of your input arrays, then count the number of arrays to determine how many columns should have default values of null.
Before looping declare a flat array of null-defaulted values for all columns.
Then use nested loops to establish default elements for each newly encountered second level key and then swap the first and second level keys when pushing values into each group. Demo
$arrays = [
['car' => '3', 'bus' => '2'],
['dog' => '1', 'car' => '2', 'bird' => '9'],
];
$defaults = array_fill(0, count($arrays), null);
$result = [];
foreach ($arrays as $i => $array) {
foreach ($array as $k => $v) {
$result[$k] ??= $defaults;
$result[$k][$i] = $v;
}
}
var_export($result);
Output:
array (
'car' =>
array (
0 => '3',
1 => '2',
),
'bus' =>
array (
0 => '2',
1 => NULL,
),
'dog' =>
array (
0 => NULL,
1 => '1',
),
'bird' =>
array (
0 => NULL,
1 => '9',
),
)