Skip to content

Instantly share code, notes, and snippets.

@hnykda
Last active Aug 26, 2021
Embed
What would you like to do?
Python snippet to convert Revolut export to Wallet
import argparse
import datetime
import pandas as pd
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument('input', help='Input revolut export file')
parser.add_argument('--output', default="rev2wall-{CURRENCY}-{TIMESTAMP}.csv", help='Input Revolut file')
return parser.parse_args()
def load_df(input_file):
_df = (pd
.read_csv(input_file, sep=';', parse_dates=['Completed Date '], thousands=',', na_values=[' '])
.rename(columns=lambda x: x.strip())
)
return _df
def get_currency(df):
return df.filter(like='Paid Out').columns[0][-4:-1]
def wrangle_format(_df, cur):
df = (_df
.assign(
currency=cur,
paid_out_currency=lambda x: x['Paid Out ({})'.format(cur)].astype(float),
paid_in_currency=lambda x: x['Paid In ({})'.format(cur)].astype(float),
amount=lambda x: x.paid_in_currency.where(x.paid_in_currency.notna(), -x.paid_out_currency),
date=lambda x: pd.to_datetime(x['Completed Date']).dt.strftime('%Y/%m/%d'),
note=lambda x: (x['Notes'] + ' ' + x['Category']).str.strip(),
type=lambda x: (x['paid_in_currency'].notna()).map({True: "Income", False: "Expense"}),
)
.rename(columns=lambda x: x.lower())
.filter(['date', 'currency', 'amount', 'note', 'type'])
)
return df
def main(input_file):
_df = load_df(input_file)
cur = get_currency(_df)
df = wrangle_format(_df, cur)
return df, cur
if __name__ == "__main__":
args = parse_args()
df, cur = main(args.input)
try:
output = args.output.format(CURRENCY=cur, TIMESTAMP=pd.datetime.now().strftime("%Y%m%dT%H%M%S"))
except KeyError:
output = args.output
df.to_csv(output, index=False, sep=";")
@hnykda

This comment has been minimized.

Copy link
Owner Author

@hnykda hnykda commented Feb 13, 2019

More info here: http://danielhnyk.cz/revolut-export-to-wallet-import/

To run it:

python revolut2wallet.py Revolut-EUR-Statement-Jan\ 2019.csv

3rd party dependencies needed can be installed by:

pip install pandas

other than that, you need Python 3.6+

@Galeaettu

This comment has been minimized.

Copy link

@Galeaettu Galeaettu commented Mar 3, 2019

Hi, I'm encountering this error,

error

@andr83

This comment has been minimized.

Copy link

@andr83 andr83 commented Mar 9, 2019

@Galeaettu, just change this 2 lines:

paid_out_currency=lambda x: x[f'Paid Out ({cur})'].notna().astype(float),
paid_in_currency=lambda x: x[f'Paid In ({cur})'].notna().astype(float),
@hnykda

This comment has been minimized.

Copy link
Owner Author

@hnykda hnykda commented Apr 21, 2019

@Galeaettu got a SyntaxError which is most likely by me using f-strings which are in Python 3.7 and not in previous versions. The .notna() addition won't help here, but changing all f-strings to .format would. So e.g. in the case of

            paid_out_currency=lambda x: x[f'Paid Out ({cur})'].astype(float),
            paid_in_currency=lambda x: x[f'Paid In ({cur})'].astype(float),

you need

            paid_out_currency=lambda x: x['Paid Out ({})'.format(cur)].astype(float),
            paid_in_currency=lambda x: x['Paid In ({})'.format(cur)].astype(float),

I changed that in the original version

@troych

This comment has been minimized.

Copy link

@troych troych commented Jun 3, 2019

Getting this on my debian machine, any idea how to solve this?

Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/pandas/core/indexes/base.py", line 2525, in get_loc
    return self._engine.get_loc(key)
  File "pandas/_libs/index.pyx", line 117, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/index.pyx", line 139, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/hashtable_class_helper.pxi", line 1265, in pandas._libs.hashtable.PyObjectHashTable.get_item
  File "pandas/_libs/hashtable_class_helper.pxi", line 1273, in pandas._libs.hashtable.PyObjectHashTable.get_item
KeyError: 'paid_in_currency'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "revolut2wallet.py", line 46, in <module>
    df, cur = main(args.input)
  File "revolut2wallet.py", line 41, in main
    df = wrangle_format(_df, cur)
  File "revolut2wallet.py", line 34, in wrangle_format
    .filter(['date', 'currency', 'amount', 'note', 'type'])
  File "/usr/local/lib/python3.4/dist-packages/pandas/core/frame.py", line 2685, in assign
    results[k] = com._apply_if_callable(v, data)
  File "/usr/local/lib/python3.4/dist-packages/pandas/core/common.py", line 477, in _apply_if_callable
    return maybe_callable(obj, **kwargs)
  File "revolut2wallet.py", line 31, in <lambda>
    type=lambda x: (x['paid_in_currency'].notna()).map({True: "Income", False: "Expense"}),
  File "/usr/local/lib/python3.4/dist-packages/pandas/core/frame.py", line 2139, in __getitem__
    return self._getitem_column(key)
  File "/usr/local/lib/python3.4/dist-packages/pandas/core/frame.py", line 2146, in _getitem_column
    return self._get_item_cache(key)
  File "/usr/local/lib/python3.4/dist-packages/pandas/core/generic.py", line 1842, in _get_item_cache
    values = self._data.get(item)
  File "/usr/local/lib/python3.4/dist-packages/pandas/core/internals.py", line 3843, in get
    loc = self.items.get_loc(item)
  File "/usr/local/lib/python3.4/dist-packages/pandas/core/indexes/base.py", line 2527, in get_loc
    return self._engine.get_loc(self._maybe_cast_indexer(key))
  File "pandas/_libs/index.pyx", line 117, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/index.pyx", line 139, in pandas._libs.index.IndexEngine.get_loc
  File "pandas/_libs/hashtable_class_helper.pxi", line 1265, in pandas._libs.hashtable.PyObjectHashTable.get_item
  File "pandas/_libs/hashtable_class_helper.pxi", line 1273, in pandas._libs.hashtable.PyObjectHashTable.get_item
KeyError: 'paid_in_currency'
@hnykda

This comment has been minimized.

Copy link
Owner Author

@hnykda hnykda commented Jun 3, 2019

@troych Because you use Python 3.4, you need at least 3.6 where an order of keywords arguments is guaranteed (technically in 3.7, but 3.6+ will work as well). Python 3.4 is retired, you should get rid of it.

@troych

This comment has been minimized.

Copy link

@troych troych commented Jul 25, 2019

That worked indeed, finally had some time to update my python install.

Second problem now, for my currency (CHF) revolut uses "," to delimit. So I've got payments of 22,70 for example. This does not seem to work with your snippet, 22,70 gets converted to 2270. If I change the delimiter to "." things work correctly.

@hnykda

This comment has been minimized.

Copy link
Owner Author

@hnykda hnykda commented Jul 25, 2019

Yeah, that's annoying. I guess that could be solved by changing thousands here.

@troych

This comment has been minimized.

Copy link

@troych troych commented Jul 25, 2019

Yeah, that's annoying. I guess that could be solved by changing thousands here.

Thanks, I've ended up doing it like this:

.read_csv(input_file, sep=';', parse_dates=['Completed Date '], decimal=',', na_values=['  '])

Works as intended now, thank you very much. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment