2 possibilities I can think of, without code:
1) Indirect import.
Create a custom entity called ContactUpdate. Add fields to hold the data you need, making sure to match field data types, length etc to Contact entity fields. Add a 1:N relationship from Contact to the new entity, which will therefore have a lookup to Contact
Write a simple workflow triggered on create of a ContactUpdate record that copies the data from the new fields up to the parent contact record.
Import your changes into the ContactUpdate entity, use the ContactID field in your import to map the lookup to Contact (instead of name).
Once built, this is easy to repeat in future.
2) Export ALL Contacts and make available for reimport, including all columns that you want to be able to update. You don't have to do a complex query, just include them all (or do this in sensible batches based on a field that is helpful such as country, or owner, or industry of parent Account).
Use one of several lookup functions in Excel (eg VLOOKUP) to match ContactID against your list of new data and fetch new values (do this in empty columns to the right of your exported data). make sure unmatched IDs in the export list show blanks, not errors (use IFERROR function to do this, for example). Copy and paste special > Values + Skip Blanks over the top of the exported data.
When you import, any rows that are unchanged are simply ignored by the import process. It uses checksums in the spreadsheet to do this, which is why you need to make sure those rows are untouched. You should see the number of rows being imported matches the number of changed rows, the rest are simply dropped.
Alternatively, use lookups to identify rows that need changes, and delete all other rows from the exported file before reimporting.