This should get you what you want. The only thing you'll need to do is add your additional columns to the Select action.
I've got the following Excel Table for this example:

The full flow is below. I'll go into each of the actions.

List rows present in a table retrieves your Table data.

Select retrieves just the Name and Id properties which we'll use to loop through later.

Compose uses a union expression to remove any duplicate values from Select as we only want one instance of each owner to loop through. The expression here is:
union(body('Select'),body('Select'))

I then create a string variable called output that will hold the final output once we combine our owners, properties, etc. I set the initial value to {

The Apply to each uses the output from our Compose since we want to loop through each unique owner.

Filter array returns rows that match the current owner's Id using the following expression:
items('Apply_to_each')?['Id']

Select Properties takes the output from Filter array and allows us to specify exactly what properties we want to include. You'd need to add your additional fields here. We don't include Name and Id here as we already have them outside the objects. The expressions used here are:
item()?['PropertyID']
item()?['Address']
item()?['Number of Bedrooms']

Compose Build then concatenates all of our data to build up the JSON array you're after. You should be able to just copy the expression below if you've named all your actions the same as what I have.
concat('"', items('Apply_to_each')?['Name'], '":{"id":"', items('Apply_to_each')?['Id'], '","property":', body('Select_Properties'), '},')

I then append that output to the output string variable.

Then outside the Apply to each we do the following:
We append a closing } to the output string variable.

And finally, we convert the output to JSON using a json expression.
json(variables('output'))
